actionMap.cpp

Engine/source/sim/actionMap.cpp

More...

Classes:

Public Defines

define
CONST_E() 2.7182818284590452353602874f

Public Variables

Public Functions

_ActionMapbind1("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n\n</a>" "When the input event is raised, the specified function will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">called.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param command The function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the action. Function must have a single boolean <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that prints <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console\n</a>" "//%val - Sent by the device letting the user <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">know\n</a>" "//<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> an input was pressed(true) or released(false)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "function testInput(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Key is down\");\n" "   <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">else\n</a>" "	  <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Key was released\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the \'K\' key <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "moveMap.bind(keyboard, k, testInput);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bind( string device, string action, string command );" )
_ActionMapbind2("@brief Associates a function and input parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n\n</a>" "When the input event is raised, the specified function will be called. Modifier flags may be specified <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process " "dead zones, input inversion, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">more.\n\n</a>" "Valid modifier <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flags:\n\n</a>" " - R - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Ranged.\n</a>" " - S - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Scaled.\n</a>" " - I - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " - D - Dead zone is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">present.\n</a>" " - N - <a href="/coding/class/classinput/">Input</a> should be re-fit <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a non-linear <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scale.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param flag Modifier flag assigned during binding, letting event know there are additional parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> consider. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param deadZone Restricted region in which device motion will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acknowledged.\n</a>" " @param scale Modifies the deadZone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">region.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the action. Must take in a single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that adjusts the pitch of the camera based on the " "mouse 's movement along the X <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">axis.\n</a>" "function testPitch(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %pitchAdj=getMouseAdjustAmount(%val);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " $mvPitch+=%pitchAdj;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "//Bind the mouse 's X axis <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testPitch <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "//DI is flagged, meaning input is inverted and has a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deadzone\n</a>" "%this.bind(mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bind( string device, string action, string flag, string deadZone, string scale, string command );" )
_ActionMapbindObj1("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> a specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify a device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, a function, and an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event happens. " "The function specified must be set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive a single boolean value <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">passed.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @param object The object or class bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.bindObj(keyboard, \"numpad1\", \"rangeChange\", %player);" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" , "ActionMap" , "bool bindObj( string device, string action, string command, SimObjectID object );" )
_ActionMapbindObj2("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> a specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify a device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, a function, and an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event happens. " "The function specified must be set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive a single boolean value passed. Modifier flags may be specified <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process " "dead zones, input inversion, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">more.\n\n</a>" "Valid modifier <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flags:\n\n</a>" " - R - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Ranged.\n</a>" " - S - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Scaled.\n</a>" " - I - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " - D - Dead zone is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">present.\n</a>" " - N - <a href="/coding/class/classinput/">Input</a> should be re-fit <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a non-linear <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scale.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param flag Modifier flag assigned during binding, letting event know there are additional parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">consider.\n</a>" " @param deadZone Restricted region in which device motion will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acknowledged.\n</a>" " @param scale Modifies the deadZone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">region.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @param object The object or class bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Bind the mouse 's movement along the x-axis <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testInput function of the <a href="/coding/class/classplayer/">Player</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class\n</a>" "//DSI is flagged, meaning input is inverted, has scale and has a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deadzone\n</a>" "%this.bindObj(mouse, \"xaxis\", \"DSI\", %deadZone, %scale, \"testInput\", %player );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );" )
ConsoleDocClass(ActionMap , "@brief ActionMaps assign platform input events <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> console <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">commands.\n\n</a>" "Any platform input event can be bound in a single, generic way. In theory, the game doesn '<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> know <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the event came from the keyboard, mouse , joystick " "or some other input device. This allows users of the game <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> map keys and actions according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> their own preferences. " "Game action maps are arranged in a stack <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> processing so individual parts of the game can define specific " "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map.\n\n</a>" " @section ActionMap_creation Creating an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "The input system allows <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It 's a simple " "three step <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">process.\n\n</a>" "1. Check <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n</a>" "2. Delete it <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> it <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n</a>" "3. Instantiate the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n\n</a>" "The following is an example of how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> create a <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap:\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(moveMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " moveMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(moveMap);" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" " @section ActionMap_binding Binding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Functions\n</a>" "Once you have created an ActionMap, you can start binding functionality <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> events. Currently, Torque 3D supports the following devices out of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">box\n\n</a>" " *<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Mouse\n\n</a>" " *<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Keyboard\n\n</a>" " *Joystick/<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Gamepad\n\n</a>" " *Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Controller\n\n</a>" "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a device and event, " "but different in how the event is interpreted. With  bind, " "you specify a device, action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, then a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">happens.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that prints <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console\n</a>" "//%val - Sent by the device letting the user <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">know\n</a>" "//<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> an input was  pressed, " "except two functions are set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">processed.\n\n</a>" "One will be called when the event is  activated, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the other is activated when the event is  broken, pass the functions as strings rather than the function <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">names.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pressed\n</a>" "function onSpaceDown()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar down!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">released\n</a>" "function onSpaceUp()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar up!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the commands onSpaceDown and onSpaceUp <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events\n</a>" "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@section ActionMap_switching Switching <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps\n</a>" "Let's say you want <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " "in the same game. On foot, spacebar may cause your player <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> push/pop the ActionMaps <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">appropriately:\n\n</a>" " First, create two separate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Create the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(moveMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " moveMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(moveMap);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(carMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " carMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(carMap);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " Next, create the two separate functions. Both will be bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar, but not the same <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console the player is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">jumping\n</a>" "function playerJump(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Player jumping!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console the vehicle is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">charging\n</a>" "function turboCharge()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "	  <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Vehicle turbo charging!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "You are now ready <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind functions <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> your ActionMaps' <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">devices:\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Bind the spacebar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the playerJump <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "// when moveMap is the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "moveMap.bind(keyboard, \"space\", playerJump);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the spacebar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the turboCharge <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "// when carMap is the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "carMap.bind(keyboard, \"space\", turboCharge);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" " Finally, you can use the push() and pop() commands on each <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> toggle activation. To activate an ActionMap, use push():\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Make moveMap the active action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map\n</a>" "//You should now be able <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> activate playerJump with <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spacebar\n</a>" "moveMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "To switch ActionMaps, first pop() the old one. Then you can push() the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">one:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Deactivate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">moveMap\n</a>" "moveMap.pop();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "//Activate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">carMap\n</a>" "carMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" " @ingroup <a href="/coding/class/classinput/">Input</a>" )
ConsoleMethod(ActionMap , bind , bool , 5 , 10 , "actionMap.bind( device, action, [modifier spec, mod...], command )" "@hide" )
ConsoleMethod(ActionMap , bindObj , bool , 6 , 11 , "(device, action, [modifier spec, mod...], command, object)" "@hide" )
DefineEngineFunction(getCurrentActionMap , ActionMap * , () , "@brief Returns the current %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap.\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineMethod(ActionMap , bindCmd , bool , (const char *device, const char *action, const char *makeCmd, const char *breakCmd) , ("") , "@brief Associates a make command and optional break command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a specified input device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "Must include parenthesis and semicolon in the make and break command <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">strings.\n\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. Can be a keyboard, mouse , joystick or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @param makeCmd The command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> execute when the device/action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">made.\n</a>" " @param breakCmd The command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> execute when the device or action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmade.\n</a>" " @return True the bind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pressed\n</a>" "function onSpaceDown()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar down!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">released\n</a>" "function onSpaceUp()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar up!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the commands onSpaceDown() and onSpaceUp() <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events\n\n</a>" "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )
DefineEngineMethod(ActionMap , getBinding , const char * , (const char *command) )
DefineEngineMethod(ActionMap , getCommand , const char * , (const char *device, const char *action) , "@brief Gets <a href="/coding/class/classactionmap/">ActionMap</a> command <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action that was bound. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return The command against the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Find what function is bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a device\ 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action\n</a>" "//In this example, \"jump()\" was assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the space key in another <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">script\n</a>" "% command)
DefineEngineMethod(ActionMap , getDeadZone , const char * , (const char *device, const char *action) , "@brief Gets the Dead zone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be a keyboard, mouse )
DefineEngineMethod(ActionMap , getScale , F32 , (const char *device, const char *action) , "@brief Get any scaling on the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be keyboard, mouse )
DefineEngineMethod(ActionMap , isInverted , bool , (const char *device, const char *action) , "@brief Determines <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the specified device and action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n\n</a>" "Should only be used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> scrolling devices or gamepad/joystick axes." "@param device The device that was bound. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action that was bound. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the specified device and action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "%<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(moveMap.isInverted(\"mouse\", \"xaxis\"))\n" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Mouse's xAxis is inverted\");" "@endtsexample\n\n" )
DefineEngineMethod(ActionMap , pop , void , () , "@brief Pop the <a href="/coding/class/classactionmap/">ActionMap</a> off the %<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "Deactivates an %<a href="/coding/class/classactionmap/">ActionMap</a> and removes it from the @<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Deactivate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">moveMap\n</a>" "moveMap.pop();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" )
DefineEngineMethod(ActionMap , push , void , () , "@brief Push the <a href="/coding/class/classactionmap/">ActionMap</a> onto the %<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "Activates an <a href="/coding/class/classactionmap/">ActionMap</a> and placees it at the top of the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Make moveMap the active action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map\n</a>" "moveMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" )
DefineEngineMethod(ActionMap , save , void , (const char *fileName, bool append) , (NULL, false) , "@brief Saves the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or dumps it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@param fileName The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> path <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> save the <a href="/coding/class/classactionmap/">ActionMap</a> to. If a filename is not specified " " the <a href="/coding/class/classactionmap/">ActionMap</a> will be dumped <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param append Whether <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write the <a href="/coding/class/classactionmap/">ActionMap</a> at the end of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or overwrite <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Write out the actionmap into the config.cs <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">file\n</a>" "moveMap.save( \"scripts/client/config.cs\" );" "@endtsexample\n\n" )
DefineEngineMethod(ActionMap , unbind , bool , (const char *device, const char *action) , "@brief Removes the binding on an input device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.unbind(\"keyboard\", \"space\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )
DefineEngineMethod(ActionMap , unbindObj , bool , (const char *device, const char *action, const char *obj) , "@brief Remove any object-binding on an input device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. Can be keyboard, mouse , joystick or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> perform unbind <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" )
bool

Detailed Description

Public Defines

CONST_E() 2.7182818284590452353602874f

Public Variables

AsciiMapping gAsciiMap []

Public Functions

_ActionMapbind1("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n\n</a>" "When the input event is raised, the specified function will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">called.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param command The function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the action. Function must have a single boolean <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that prints <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console\n</a>" "//%val - Sent by the device letting the user <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">know\n</a>" "//<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> an input was pressed(true) or released(false)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "function testInput(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Key is down\");\n" "   <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">else\n</a>" "	  <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Key was released\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the \'K\' key <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "moveMap.bind(keyboard, k, testInput);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bind( string device, string action, string command );" )

_ActionMapbind2("@brief Associates a function and input parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">event.\n\n</a>" "When the input event is raised, the specified function will be called. Modifier flags may be specified <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process " "dead zones, input inversion, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">more.\n\n</a>" "Valid modifier <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flags:\n\n</a>" " - R - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Ranged.\n</a>" " - S - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Scaled.\n</a>" " - I - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " - D - Dead zone is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">present.\n</a>" " - N - <a href="/coding/class/classinput/">Input</a> should be re-fit <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a non-linear <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scale.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param flag Modifier flag assigned during binding, letting event know there are additional parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> consider. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param deadZone Restricted region in which device motion will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acknowledged.\n</a>" " @param scale Modifies the deadZone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">region.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the action. Must take in a single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that adjusts the pitch of the camera based on the " "mouse 's movement along the X <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">axis.\n</a>" "function testPitch(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %pitchAdj=getMouseAdjustAmount(%val);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " $mvPitch+=%pitchAdj;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "//Bind the mouse 's X axis <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testPitch <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "//DI is flagged, meaning input is inverted and has a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deadzone\n</a>" "%this.bind(mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bind( string device, string action, string flag, string deadZone, string scale, string command );" )

_ActionMapbindObj1("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> a specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify a device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, a function, and an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event happens. " "The function specified must be set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive a single boolean value <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">passed.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @param object The object or class bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.bindObj(keyboard, \"numpad1\", \"rangeChange\", %player);" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" , "ActionMap" , "bool bindObj( string device, string action, string command, SimObjectID object );" )

_ActionMapbindObj2("@brief Associates a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an input event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> a specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify a device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, a function, and an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event happens. " "The function specified must be set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> receive a single boolean value passed. Modifier flags may be specified <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> process " "dead zones, input inversion, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">more.\n\n</a>" "Valid modifier <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flags:\n\n</a>" " - R - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Ranged.\n</a>" " - S - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Scaled.\n</a>" " - I - <a href="/coding/class/classinput/">Input</a> is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " - D - Dead zone is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">present.\n</a>" " - N - <a href="/coding/class/classinput/">Input</a> should be re-fit <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a non-linear <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scale.\n\n</a>" " @param device The input device, such as mouse or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboard.\n</a>" " @param action The input event, such as space, button0 , <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">etc.\n</a>" " @param flag Modifier flag assigned during binding, letting event know there are additional parameters <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">consider.\n</a>" " @param deadZone Restricted region in which device motion will not be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acknowledged.\n</a>" " @param scale Modifies the deadZone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">region.\n</a>" " @param command The function bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @param object The object or class bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Bind the mouse 's movement along the x-axis <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the testInput function of the <a href="/coding/class/classplayer/">Player</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">class\n</a>" "//DSI is flagged, meaning input is inverted, has scale and has a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">deadzone\n</a>" "%this.bindObj(mouse, \"xaxis\", \"DSI\", %deadZone, %scale, \"testInput\", %player );\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" , "ActionMap" , "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );" )

ConsoleDocClass(ActionMap , "@brief ActionMaps assign platform input events <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> console <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">commands.\n\n</a>" "Any platform input event can be bound in a single, generic way. In theory, the game doesn '<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> know <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the event came from the keyboard, mouse , joystick " "or some other input device. This allows users of the game <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> map keys and actions according <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> their own preferences. " "Game action maps are arranged in a stack <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> processing so individual parts of the game can define specific " "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map.\n\n</a>" " @section ActionMap_creation Creating an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "The input system allows <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It 's a simple " "three step <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">process.\n\n</a>" "1. Check <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n</a>" "2. Delete it <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> it <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">exists\n</a>" "3. Instantiate the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n\n</a>" "The following is an example of how <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> create a <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap:\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(moveMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " moveMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(moveMap);" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" " @section ActionMap_binding Binding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Functions\n</a>" "Once you have created an ActionMap, you can start binding functionality <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> events. Currently, Torque 3D supports the following devices out of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">box\n\n</a>" " *<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Mouse\n\n</a>" " *<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Keyboard\n\n</a>" " *Joystick/<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Gamepad\n\n</a>" " *Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Controller\n\n</a>" "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a device and event, " "but different in how the event is interpreted. With  bind, " "you specify a device, action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, then a function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">happens.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Simple function that prints <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console\n</a>" "//%val - Sent by the device letting the user <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">know\n</a>" "//<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> an input was  pressed, " "except two functions are set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be called when the event is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">processed.\n\n</a>" "One will be called when the event is  activated, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the other is activated when the event is  broken, pass the functions as strings rather than the function <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">names.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pressed\n</a>" "function onSpaceDown()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar down!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">released\n</a>" "function onSpaceUp()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar up!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the commands onSpaceDown and onSpaceUp <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events\n</a>" "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@section ActionMap_switching Switching <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps\n</a>" "Let's say you want <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " "in the same game. On foot, spacebar may cause your player <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> push/pop the ActionMaps <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">appropriately:\n\n</a>" " First, create two separate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Create the two <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMaps\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(moveMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " moveMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(moveMap);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(isObject(carMap))\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " carMap.delete();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classactionmap/">ActionMap</a>(carMap);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " Next, create the two separate functions. Both will be bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar, but not the same <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console the player is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">jumping\n</a>" "function playerJump(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Player jumping!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console the vehicle is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">charging\n</a>" "function turboCharge()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "	  <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Vehicle turbo charging!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "You are now ready <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind functions <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> your ActionMaps' <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">devices:\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Bind the spacebar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the playerJump <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "// when moveMap is the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "moveMap.bind(keyboard, \"space\", playerJump);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the spacebar <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the turboCharge <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function\n</a>" "// when carMap is the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap\n</a>" "carMap.bind(keyboard, \"space\", turboCharge);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" " Finally, you can use the push() and pop() commands on each <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> toggle activation. To activate an ActionMap, use push():\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Make moveMap the active action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map\n</a>" "//You should now be able <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> activate playerJump with <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spacebar\n</a>" "moveMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "To switch ActionMaps, first pop() the old one. Then you can push() the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">one:\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Deactivate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">moveMap\n</a>" "moveMap.pop();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "//Activate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">carMap\n</a>" "carMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" " @ingroup <a href="/coding/class/classinput/">Input</a>" )

ConsoleMethod(ActionMap , bind , bool , 5 , 10 , "actionMap.bind( device, action, [modifier spec, mod...], command )" "@hide" )

ConsoleMethod(ActionMap , bindObj , bool , 6 , 11 , "(device, action, [modifier spec, mod...], command, object)" "@hide" )

DefineEngineFunction(getCurrentActionMap , ActionMap * , () , "@brief Returns the current %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ActionMap.\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )

DefineEngineMethod(ActionMap , bindCmd , bool , (const char *device, const char *action, const char *makeCmd, const char *breakCmd) , ("") , "@brief Associates a make command and optional break command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a specified input device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "Must include parenthesis and semicolon in the make and break command <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">strings.\n\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. Can be a keyboard, mouse , joystick or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @param makeCmd The command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> execute when the device/action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">made.\n</a>" " @param breakCmd The command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> execute when the device or action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">unmade.\n</a>" " @return True the bind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pressed\n</a>" "function onSpaceDown()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar down!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Print <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console when the spacebar is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">released\n</a>" "function onSpaceUp()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Space bar up!\");\n" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Bind the commands onSpaceDown() and onSpaceUp() <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> spacebar <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events\n\n</a>" "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )

DefineEngineMethod(ActionMap , getBinding , const char * , (const char *command) )

DefineEngineMethod(ActionMap , getCommand , const char * , (const char *device, const char *action) , "@brief Gets <a href="/coding/class/classactionmap/">ActionMap</a> command <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action that was bound. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return The command against the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Find what function is bound <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a device\ 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action\n</a>" "//In this example, \"jump()\" was assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the space key in another <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">script\n</a>" "% command)

DefineEngineMethod(ActionMap , getDeadZone , const char * , (const char *device, const char *action) , "@brief Gets the Dead zone <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be a keyboard, mouse )

DefineEngineMethod(ActionMap , getScale , F32 , (const char *device, const char *action) , "@brief Get any scaling on the specified device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n\n</a>" "@param device The device that was bound. Can be keyboard, mouse )

DefineEngineMethod(ActionMap , isInverted , bool , (const char *device, const char *action) , "@brief Determines <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the specified device and action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n\n</a>" "Should only be used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> scrolling devices or gamepad/joystick axes." "@param device The device that was bound. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action that was bound. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the specified device and action is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">inverted.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "%<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a>(moveMap.isInverted(\"mouse\", \"xaxis\"))\n" " <a href="/coding/file/ggendoflinefix_8txt/#ggendoflinefix_8txt_1a7f8fee038817022b75b8865e5da4eba3">echo</a>(\"Mouse's xAxis is inverted\");" "@endtsexample\n\n" )

DefineEngineMethod(ActionMap , pop , void , () , "@brief Pop the <a href="/coding/class/classactionmap/">ActionMap</a> off the %<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "Deactivates an %<a href="/coding/class/classactionmap/">ActionMap</a> and removes it from the @<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Deactivate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">moveMap\n</a>" "moveMap.pop();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" )

DefineEngineMethod(ActionMap , push , void , () , "@brief Push the <a href="/coding/class/classactionmap/">ActionMap</a> onto the %<a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "Activates an <a href="/coding/class/classactionmap/">ActionMap</a> and placees it at the top of the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stack.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Make moveMap the active action <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">map\n</a>" "moveMap.push();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/class/classactionmap/">ActionMap</a>" )

DefineEngineMethod(ActionMap , save , void , (const char *fileName, bool append) , (NULL, false) , "@brief Saves the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or dumps it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@param fileName The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> path <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> save the <a href="/coding/class/classactionmap/">ActionMap</a> to. If a filename is not specified " " the <a href="/coding/class/classactionmap/">ActionMap</a> will be dumped <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param append Whether <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write the <a href="/coding/class/classactionmap/">ActionMap</a> at the end of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or overwrite <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">it.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Write out the actionmap into the config.cs <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">file\n</a>" "moveMap.save( \"scripts/client/config.cs\" );" "@endtsexample\n\n" )

DefineEngineMethod(ActionMap , unbind , bool , (const char *device, const char *action) , "@brief Removes the binding on an input device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. Can be a keyboard, mouse , joystick or a <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.unbind(\"keyboard\", \"space\");\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )

DefineEngineMethod(ActionMap , unbindObj , bool , (const char *device, const char *action, const char *obj) , "@brief Remove any object-binding on an input device and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@param device The device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind to. Can be keyboard, mouse , joystick or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">gamepad.\n</a>" " @param action The device action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> unbind from. The action is dependant upon the device. Specify a key <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">keyboards.\n</a>" " @param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> perform unbind <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a2594a51175f310ed96ad6cd7d6514878">if</a> the device was unknown or description <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">failed.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n\n</a>" )

dIsDecentChar(U8 c)

IMPLEMENT_CONOBJECT(ActionMap )

   1
   2//-----------------------------------------------------------------------------
   3// Copyright (c) 2012 GarageGames, LLC
   4//
   5// Permission is hereby granted, free of charge, to any person obtaining a copy
   6// of this software and associated documentation files (the "Software"), to
   7// deal in the Software without restriction, including without limitation the
   8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   9// sell copies of the Software, and to permit persons to whom the Software is
  10// furnished to do so, subject to the following conditions:
  11//
  12// The above copyright notice and this permission notice shall be included in
  13// all copies or substantial portions of the Software.
  14//
  15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21// IN THE SOFTWARE.
  22//-----------------------------------------------------------------------------
  23
  24#include "sim/actionMap.h"
  25#include "console/console.h"
  26#include "platform/platform.h"
  27#include "platform/platformInput.h"
  28#include "platform/platformAssert.h"
  29#include "core/stream/fileStream.h"
  30#include "math/mMathFn.h"
  31#include "console/engineAPI.h"
  32#include "math/mQuat.h"
  33#include "math/mAngAxis.h"
  34
  35#define CONST_E 2.7182818284590452353602874f
  36
  37IMPLEMENT_CONOBJECT(ActionMap);
  38
  39ConsoleDocClass( ActionMap,
  40   "@brief ActionMaps assign platform input events to console commands.\n\n"
  41
  42   "Any platform input event can be bound in a single, generic way. In theory, the game doesn't need to know if the event came from the keyboard, mouse, joystick "
  43   "or some other input device. This allows users of the game to map keys and actions according to their own preferences. "
  44   "Game action maps are arranged in a stack for processing so individual parts of the game can define specific "
  45   "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action map.\n\n"
  46
  47   "@section ActionMap_creation Creating an ActionMap\n"
  48
  49   "The input system allows for the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It's a simple "
  50   "three step process.\n\n"
  51   "1. Check to see if the ActionMap exists\n"
  52   "2. Delete it if it exists\n"
  53   "3. Instantiate the ActionMap\n\n"
  54
  55   "The following is an example of how to create a new ActionMap:\n"
  56
  57   "@tsexample\n"
  58   "if ( isObject( moveMap ) )\n"
  59   "  moveMap.delete();\n"
  60   "new ActionMap(moveMap);"
  61   "@endtsexample\n\n\n"
  62   
  63   "@section ActionMap_binding Binding Functions\n"
  64   "Once you have created an ActionMap, you can start binding functionality to events. Currently, Torque 3D supports the following devices out of the box\n\n"
  65   "* Mouse\n\n"
  66   "* Keyboard\n\n"
  67   "* Joystick/Gamepad\n\n"
  68   "* Xbox 360 Controller\n\n"
  69
  70   "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality to a device and event, "
  71   "but different in how the event is interpreted. With bind(), "
  72   "you specify a device, action to bind, then a function to be called when the event happens.\n\n"
  73
  74   "@tsexample\n"
  75   "// Simple function that prints to console\n"
  76   "// %val - Sent by the device letting the user know\n"
  77   "// if an input was pressed (true) or released (false)\n"
  78   "function testInput(%val)\n"
  79   "{\n"
  80   "   if(%val)\n"
  81   "    echo(\"Key is down\");\n"
  82   "   else\n"
  83   "    echo(\"Key was released\");\n"
  84   "}\n\n"
  85   "// Bind the \'K\' key to the testInput function\n"
  86   "moveMap.bind(keyboard, \"k\", testInput);\n\n"
  87   "@endtsexample\n\n\n"
  88
  89   "bindCmd is an alternative method for binding commands. This function is similar to bind(), "
  90   "except two functions are set to be called when the event is processed.\n\n"
  91   "One will be called when the event is activated (input down), while the other is activated when the event is broken (input release). "
  92   "When using bindCmd(), pass the functions as strings rather than the function names.\n\n"
  93
  94   "@tsexample\n"
  95   "// Print to the console when the spacebar is pressed\n"
  96   "function onSpaceDown()\n"
  97   "{\n"
  98   "   echo(\"Space bar down!\");\n"
  99   "}\n\n"
 100
 101   "// Print to the console when the spacebar is released\n"
 102   "function onSpaceUp()\n"
 103   "{\n"
 104   "   echo(\"Space bar up!\");\n"
 105   "}\n\n"
 106
 107   "// Bind the commands onSpaceDown and onSpaceUp to spacebar events\n"
 108   "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n"
 109   "@endtsexample\n\n"
 110   
 111   "@section ActionMap_switching Switching ActionMaps\n"
 112   "Let's say you want to have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls "
 113   "in the same game. On foot, spacebar may cause your player to jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need to push/pop the ActionMaps appropriately:\n\n"
 114
 115   "First, create two separate ActionMaps:\n\n"
 116   "@tsexample\n"
 117   "// Create the two ActionMaps\n"
 118   "if ( isObject( moveMap ) )\n"
 119   "  moveMap.delete();\n"
 120   "new ActionMap(moveMap);\n\n"
 121   "if ( isObject( carMap ) )\n"
 122   "  carMap.delete();\n"
 123   "new ActionMap(carMap);\n\n"
 124   "@endtsexample\n\n"
 125
 126   "Next, create the two separate functions. Both will be bound to spacebar, but not the same ActionMap:\n\n"
 127   "@tsexample\n"
 128   "// Print to the console the player is jumping\n"
 129   "function playerJump(%val)\n"
 130   "{\n"
 131   "   if(%val)\n"
 132   "    echo(\"Player jumping!\");\n"
 133   "}\n\n"
 134   "// Print to the console the vehicle is charging\n"
 135   "function turboCharge()\n"
 136   "{\n"
 137   "   if(%val)\n"
 138   "    echo(\"Vehicle turbo charging!\");\n"
 139   "}\n"
 140   "@endtsexample\n\n"
 141   
 142   "You are now ready to bind functions to your ActionMaps' devices:\n\n"
 143
 144   "@tsexample\n"
 145   "// Bind the spacebar to the playerJump function\n"
 146   "// when moveMap is the active ActionMap\n"
 147   "moveMap.bind(keyboard, \"space\", playerJump);\n\n"
 148   "// Bind the spacebar to the turboCharge function\n"
 149   "// when carMap is the active ActionMap\n"
 150   "carMap.bind(keyboard, \"space\", turboCharge);\n"
 151   "@endtsexample\n"
 152
 153   "Finally, you can use the push() and pop() commands on each ActionMap to toggle activation. To activate an ActionMap, use push():\n\n"
 154
 155   "@tsexample\n"
 156   "// Make moveMap the active action map\n"
 157   "// You should now be able to activate playerJump with spacebar\n"
 158   "moveMap.push();\n"
 159   "@endtsexample\n\n"
 160
 161   "To switch ActionMaps, first pop() the old one. Then you can push() the new one:\n\n"
 162
 163   "@tsexample\n"
 164   "// Deactivate moveMap\n"
 165   "moveMap.pop();\n\n"
 166   "// Activate carMap\n"
 167   "carMap.push();\n\n"
 168   "@endtsexample\n\n\n"
 169
 170   "@ingroup Input"
 171   
 172);
 173
 174// This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys.
 175static inline bool dIsDecentChar(U8 c)
 176{
 177   return ((U8(0xa0) <= c) || (( U8(0x21) <= c) && (c <= U8(0x7e))) || ((U8(0x91) <= c) && (c <= U8(0x92))));
 178}
 179
 180struct AsciiMapping
 181{
 182   const char* pDescription;
 183   U16         asciiCode;
 184};
 185
 186extern AsciiMapping gAsciiMap[];
 187
 188//------------------------------------------------------------------------------
 189//-------------------------------------- Action maps
 190//
 191Vector<ActionMap::BreakEntry> ActionMap::smBreakTable(__FILE__, __LINE__);
 192
 193
 194//------------------------------------------------------------------------------
 195ActionMap::ActionMap()
 196{
 197   VECTOR_SET_ASSOCIATION(mDeviceMaps);
 198}
 199
 200//------------------------------------------------------------------------------
 201ActionMap::~ActionMap()
 202{
 203   for (U32 i = 0; i < mDeviceMaps.size(); i++)
 204      delete mDeviceMaps[i];
 205   mDeviceMaps.clear();
 206}
 207
 208//------------------------------------------------------------------------------
 209ActionMap::DeviceMap::~DeviceMap()
 210{
 211   for(U32 i = 0; i < nodeMap.size(); i++)
 212   {
 213      dFree(nodeMap[i].makeConsoleCommand);
 214      dFree(nodeMap[i].breakConsoleCommand);
 215   }
 216}
 217
 218//------------------------------------------------------------------------------
 219bool ActionMap::onAdd()
 220{
 221   if (Parent::onAdd() == false)
 222      return false;
 223
 224   Sim::getActionMapGroup()->addObject(this);
 225
 226   return true;
 227}
 228
 229//--------------------------------------------------------------------------
 230void ActionMap::dumpActionMap(const char* fileName, const bool append) const
 231{
 232   if (fileName != NULL) {
 233      // Dump the deletion, and creation script commands, followed by all the binds
 234      //  to a script.
 235
 236      FileStream *iostrm;
 237      if((iostrm = FileStream::createAndOpen( fileName, append ? Torque::FS::File::WriteAppend : Torque::FS::File::Write )) == NULL)
 238      {
 239         Con::errorf( "Unable to open file '%s' for writing.", fileName );
 240         return;
 241      }
 242
 243      char lineBuffer[1024];
 244      if ( append )
 245         iostrm->setPosition( iostrm->getStreamSize() );
 246      else
 247      {
 248         // IMPORTANT -- do NOT change the following line, it identifies the file as an input map file
 249         dStrcpy( lineBuffer, "// Torque Input Map File\n" );
 250         iostrm->write( dStrlen( lineBuffer ), lineBuffer );
 251      }
 252
 253      dSprintf(lineBuffer, 1023, "if (isObject(%s)) %s.delete();\n"
 254                                 "new ActionMap(%s);\n", getName(), getName(), getName());
 255      iostrm->write(dStrlen(lineBuffer), lineBuffer);
 256
 257      // Dump all the binds to the console...
 258      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
 259         const DeviceMap* pDevMap = mDeviceMaps[i];
 260
 261         char devbuffer[32];
 262         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
 263
 264         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
 265            const Node& rNode = pDevMap->nodeMap[j];
 266
 267            const char* pModifierString = getModifierString(rNode.modifiers);
 268
 269            char objectbuffer[64];
 270            if (getKeyString(rNode.action, objectbuffer) == false)
 271               continue;
 272
 273            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
 274
 275            dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"",
 276                                        getName(),
 277                                        command,
 278                                        devbuffer,
 279                                        pModifierString, objectbuffer);
 280
 281            if (rNode.flags & (Node::HasScale</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da0d0a0fd89861c0261529d640c60c2ca9">Node::HasDeadZone</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da9972ef67eef430a6dfdf543d1cd9d73b">Node::Ranged</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da8d324e3ac6f233063c8846a674600cc9">Node::Inverted)) {
 282               char buff[10];
 283               U32 curr = 0;
 284               buff[curr++] = ',';
 285               buff[curr++] = ' ';
 286               if (rNode.flags & Node::HasScale)
 287                  buff[curr++] = 'S';
 288               if (rNode.flags & Node::Ranged)
 289                  buff[curr++] = 'R';
 290               if (rNode.flags & Node::HasDeadZone)
 291                  buff[curr++] = 'D';
 292               if (rNode.flags & Node::Inverted)
 293                  buff[curr++] = 'I';
 294               buff[curr] = '\0';
 295
 296               dStrcat(lineBuffer, buff);
 297            }
 298
 299            if (rNode.flags & Node::HasDeadZone) {
 300               char buff[64];
 301               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
 302               dStrcat(lineBuffer, buff);
 303            }
 304
 305            if (rNode.flags & Node::HasScale) {
 306               char buff[64];
 307               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
 308               dStrcat(lineBuffer, buff);
 309            }
 310
 311            if (rNode.flags & Node::BindCmd) {
 312               if (rNode.makeConsoleCommand) {
 313                  dStrcat(lineBuffer, ", \"");
 314                  U32 pos = dStrlen(lineBuffer);
 315                  expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
 316                  dStrcat(lineBuffer, "\"");
 317               } else {
 318                  dStrcat(lineBuffer, ", \"\"");
 319               }
 320               if (rNode.breakConsoleCommand) {
 321                  dStrcat(lineBuffer, ", \"");
 322                  U32 pos = dStrlen(lineBuffer);
 323                  expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
 324                  dStrcat(lineBuffer, "\"");
 325               }
 326               else
 327                  dStrcat(lineBuffer, ", \"\"");
 328            } else {
 329               dStrcat(lineBuffer, ", ");
 330               dStrcat(lineBuffer, rNode.consoleFunction);
 331            }
 332
 333            dStrcat(lineBuffer, ");\n");
 334            iostrm->write(dStrlen(lineBuffer), lineBuffer);
 335         }
 336      }
 337
 338      delete iostrm;
 339   }
 340   else {
 341      // Dump all the binds to the console...
 342      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
 343         const DeviceMap* pDevMap = mDeviceMaps[i];
 344
 345         char devbuffer[32];
 346         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
 347
 348         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
 349            const Node& rNode = pDevMap->nodeMap[j];
 350
 351            const char* pModifierString = getModifierString(rNode.modifiers);
 352
 353            char keybuffer[64];
 354            if (getKeyString(rNode.action, keybuffer) == false)
 355               continue;
 356
 357            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
 358
 359            char finalBuffer[1024];
 360            dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"",
 361                                        getName(),
 362                                        command,
 363                                        devbuffer,
 364                                        pModifierString, keybuffer);
 365
 366            if (rNode.flags & (Node::HasScale</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da0d0a0fd89861c0261529d640c60c2ca9">Node::HasDeadZone</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da9972ef67eef430a6dfdf543d1cd9d73b">Node::Ranged</a>|<a href="/coding/class/structactionmap_1_1node/#structactionmap_1_1node_1a81f7833cc50d67ef9f97dbfa8fe0107da8d324e3ac6f233063c8846a674600cc9">Node::Inverted)) {
 367               char buff[10];
 368               U32 curr = 0;
 369               buff[curr++] = ',';
 370               buff[curr++] = ' ';
 371               if (rNode.flags & Node::HasScale)
 372                  buff[curr++] = 'S';
 373               if (rNode.flags & Node::Ranged)
 374                  buff[curr++] = 'R';
 375               if (rNode.flags & Node::HasDeadZone)
 376                  buff[curr++] = 'D';
 377               if (rNode.flags & Node::Inverted)
 378                  buff[curr++] = 'I';
 379               buff[curr] = '\0';
 380
 381               dStrcat(finalBuffer, buff);
 382            }
 383
 384            if (rNode.flags & Node::HasDeadZone) {
 385               char buff[64];
 386               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
 387               dStrcat(finalBuffer, buff);
 388            }
 389
 390            if (rNode.flags & Node::HasScale) {
 391               char buff[64];
 392               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
 393               dStrcat(finalBuffer, buff);
 394            }
 395
 396            if (rNode.flags & Node::BindCmd) {
 397               if (rNode.makeConsoleCommand) {
 398                  dStrcat(finalBuffer, ", \"");
 399                  dStrcat(finalBuffer, rNode.makeConsoleCommand);
 400                  dStrcat(finalBuffer, "\"");
 401               } else {
 402                  dStrcat(finalBuffer, ", \"\"");
 403               }
 404               if (rNode.breakConsoleCommand) {
 405                  dStrcat(finalBuffer, ", \"");
 406                  dStrcat(finalBuffer, rNode.breakConsoleCommand);
 407                  dStrcat(finalBuffer, "\"");
 408               }
 409               else
 410                  dStrcat(finalBuffer, ", \"\"");
 411            } else {
 412               dStrcat(finalBuffer, ", ");
 413               dStrcat(finalBuffer, rNode.consoleFunction);
 414            }
 415
 416            dStrcat(finalBuffer, ");");
 417            Con::printf(finalBuffer);
 418         }
 419      }
 420   }
 421}
 422
 423//--------------------------------------------------------------------------
 424bool ActionMap::createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor)
 425{
 426   char copyBuffer[256];
 427   dStrcpy(copyBuffer, pEventString);
 428
 429   // Do we have modifiers?
 430   char* pSpace = dStrchr(copyBuffer, ' ');
 431   char* pObjectString;
 432   if (pSpace != NULL) {
 433      // Yes.  Parse them out...
 434      //
 435      pDescriptor->flags = 0;
 436      pObjectString      = pSpace + 1;
 437      pSpace[0]          = '\0';
 438
 439      char* pModifier = dStrtok(copyBuffer, "-");
 440      while (pModifier != NULL) {
 441         if (dStricmp(pModifier, "shift") == 0) {
 442            pDescriptor->flags |= SI_SHIFT;
 443         } else if (dStricmp(pModifier, "ctrl") == 0) {
 444            pDescriptor->flags |= SI_CTRL;
 445         } else if (dStricmp(pModifier, "alt") == 0) {
 446            pDescriptor->flags |= SI_ALT;
 447         } else if (dStricmp(pModifier, "cmd") == 0) {
 448            pDescriptor->flags |= SI_ALT;
 449         } else if (dStricmp(pModifier, "opt") == 0) {
 450            pDescriptor->flags |= SI_MAC_OPT;
 451         }
 452
 453         pModifier = dStrtok(NULL, "-");
 454      }
 455   } else {
 456      // No.
 457      pDescriptor->flags = 0;
 458      pObjectString      = copyBuffer;
 459   }
 460
 461   // Now we need to map the key string to the proper KEY code from event.h
 462   //
 463   AssertFatal(dStrlen(pObjectString) != 0, "Error, no key was specified!");
 464
 465   if (dStrlen(pObjectString) == 1)
 466   {
 467      if (dIsDecentChar(*pObjectString)) // includes foreign chars
 468      {
 469         U16 asciiCode = (*pObjectString);
 470         // clear out the FF in upper 8bits for foreign keys??
 471         asciiCode &= 0xFF;
 472         U16 keyCode = Input::getKeyCode(asciiCode);
 473         if ( keyCode >= KEY_0 )
 474         {
 475            pDescriptor->eventType = SI_KEY;
 476            pDescriptor->eventCode = keyCode;
 477            return true;
 478         }
 479         else if (dIsalpha(*pObjectString) == true)
 480         {
 481            pDescriptor->eventType = SI_KEY;
 482            pDescriptor->eventCode = KEY_A+dTolower(*pObjectString)-'a';
 483            return true;
 484         }
 485         else if (dIsdigit(*pObjectString) == true)
 486         {
 487            pDescriptor->eventType = SI_KEY;
 488            pDescriptor->eventCode = KEY_0+(*pObjectString)-'0';
 489            return true;
 490         }
 491      }
 492      return false;
 493   }
 494   else
 495   {
 496      pDescriptor->eventCode = 0;
 497      // Gotta search through the Ascii table...
 498      for (U16 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++)
 499      {
 500         if (dStricmp(pObjectString, gAsciiMap[i].pDescription) == 0)
 501         {
 502            U16 asciiCode = gAsciiMap[i].asciiCode;
 503            U16 keyCode   = Input::getKeyCode(asciiCode);
 504            if ( keyCode >= KEY_0 )
 505            {
 506               pDescriptor->eventType = SI_KEY;
 507               pDescriptor->eventCode = keyCode;
 508               return(true);
 509
 510            }
 511            else
 512            {
 513               break;
 514            }
 515         }
 516      }
 517      // Didn't find an ascii match. Check the virtual map table
 518      //for (U32 j = 0; gVirtualMap[j].code != 0xFFFFFFFF; j++)
 519      //{
 520      //   if (dStricmp(pObjectString, gVirtualMap[j].pDescription) == 0)
 521      //   {
 522      //      pDescriptor->eventType = gVirtualMap[j].type;
 523      //      pDescriptor->eventCode = gVirtualMap[j].code;
 524      //      return true;
 525      //   }
 526      //}
 527      InputEventManager::VirtualMapData* data = INPUTMGR->findVirtualMap(pObjectString);
 528      if(data)
 529      {
 530         pDescriptor->eventType = data->type;
 531         pDescriptor->eventCode = data->code;
 532         return true;
 533      }
 534   }
 535   return false;
 536}
 537
 538//------------------------------------------------------------------------------
 539ActionMap::Node* ActionMap::getNode(const U32 inDeviceType, const U32 inDeviceInst,
 540                   const U32 inModifiers,  const U32 inAction,SimObject* object /*= NULL*/)
 541{
 542   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 543   //
 544   DeviceMap* pDeviceMap = NULL;
 545   U32 i;
 546   for (i = 0; i < mDeviceMaps.size(); i++) 
 547   {
 548      if (mDeviceMaps[i]->deviceType == inDeviceType &&
 549          mDeviceMaps[i]->deviceInst == inDeviceInst) {
 550         pDeviceMap = mDeviceMaps[i];
 551         break;
 552      }
 553   }
 554   if (pDeviceMap == NULL) 
 555   {
 556      mDeviceMaps.increment();
 557      mDeviceMaps.last() = new DeviceMap;
 558      pDeviceMap = mDeviceMaps.last();
 559
 560      pDeviceMap->deviceInst = inDeviceInst;
 561      pDeviceMap->deviceType = inDeviceType;
 562   }
 563
 564   for (i = 0; i < pDeviceMap->nodeMap.size(); i++) 
 565   {
 566      if (pDeviceMap->nodeMap[i].modifiers == inModifiers &&
 567          pDeviceMap->nodeMap[i].action    == inAction &&
 568          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) // Check for an object match if the object exists 
 569      {
 570         return &pDeviceMap->nodeMap[i];
 571      }
 572   }
 573
 574   // If we're here, the node doesn't exist.  create it.
 575   pDeviceMap->nodeMap.increment();
 576
 577   Node* pRetNode = &pDeviceMap->nodeMap.last();
 578   pRetNode->modifiers = inModifiers;
 579   pRetNode->action    = inAction;
 580
 581   pRetNode->flags         = 0;
 582   pRetNode->deadZoneBegin = 0.0;
 583   pRetNode->deadZoneEnd   = 0.0;
 584   pRetNode->scaleFactor   = 1.0;
 585
 586   pRetNode->consoleFunction = NULL;
 587   pRetNode->makeConsoleCommand = NULL;
 588   pRetNode->breakConsoleCommand = NULL;
 589
 590   //[neob, 5/7/2007 - #2975]
 591   pRetNode->object = 0;
 592
 593   return pRetNode;
 594}
 595
 596//------------------------------------------------------------------------------
 597void ActionMap::removeNode(const U32 inDeviceType, const U32 inDeviceInst, const U32 inModifiers, const U32 inAction, SimObject* object /*= NULL*/)
 598{
 599   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 600   //
 601   DeviceMap* pDeviceMap = NULL;
 602   U32 i;
 603   for (i = 0; i < mDeviceMaps.size(); i++) {
 604      if (mDeviceMaps[i]->deviceType == inDeviceType &&
 605          mDeviceMaps[i]->deviceInst == inDeviceInst) {
 606         pDeviceMap = mDeviceMaps[i];
 607         break;
 608      }
 609   }
 610
 611   if (pDeviceMap == NULL)
 612      return;
 613
 614   U32 realMods = inModifiers;
 615   if (realMods & SI_SHIFT)
 616      realMods |= SI_SHIFT;
 617   if (realMods & SI_CTRL)
 618      realMods |= SI_CTRL;
 619   if (realMods & SI_ALT)
 620      realMods |= SI_ALT;
 621   if (realMods & SI_MAC_OPT)
 622      realMods |= SI_MAC_OPT;
 623
 624   for (i = 0; i < pDeviceMap->nodeMap.size(); i++) {
 625      if (pDeviceMap->nodeMap[i].modifiers == realMods &&
 626          pDeviceMap->nodeMap[i].action    == inAction &&
 627          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) 
 628      {
 629          dFree(pDeviceMap->nodeMap[i].makeConsoleCommand);
 630          dFree(pDeviceMap->nodeMap[i].breakConsoleCommand);
 631          pDeviceMap->nodeMap.erase(i);
 632      }
 633   }
 634}
 635
 636//------------------------------------------------------------------------------
 637const ActionMap::Node* ActionMap::findNode(const U32 inDeviceType, const U32 inDeviceInst,
 638                    const U32 inModifiers,  const U32 inAction)
 639{
 640   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 641   //
 642   DeviceMap* pDeviceMap = NULL;
 643   U32 i;
 644   for (i = 0; i < mDeviceMaps.size(); i++)
 645   {
 646      if (mDeviceMaps[i]->deviceType == inDeviceType && mDeviceMaps[i]->deviceInst == inDeviceInst)
 647      {
 648         pDeviceMap = mDeviceMaps[i];
 649         break;
 650      }
 651   }
 652
 653   if (pDeviceMap == NULL)
 654      return NULL;
 655
 656   U32 realMods = inModifiers;
 657   if (realMods & SI_SHIFT)
 658      realMods |= SI_SHIFT;
 659   if (realMods & SI_CTRL)
 660      realMods |= SI_CTRL;
 661   if (realMods & SI_ALT)
 662      realMods |= SI_ALT;
 663   if (realMods & SI_MAC_OPT)
 664      realMods |= SI_MAC_OPT;
 665
 666   for (i = 0; i < pDeviceMap->nodeMap.size(); i++)
 667   {
 668      // Special case for an ANYKEY bind...
 669      if (pDeviceMap->nodeMap[i].action == KEY_ANYKEY 
 670         && pDeviceMap->nodeMap[i].modifiers == realMods 
 671         && dIsDecentChar(inAction)
 672         && inAction <= U8_MAX)
 673         return &pDeviceMap->nodeMap[i];
 674
 675      if (pDeviceMap->nodeMap[i].modifiers == realMods 
 676         && pDeviceMap->nodeMap[i].action == inAction)
 677         return &pDeviceMap->nodeMap[i];
 678   }
 679
 680   return NULL;
 681}
 682
 683//------------------------------------------------------------------------------
 684bool ActionMap::findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
 685{
 686   devMapIndex = 0;
 687   nodeIndex = 0;
 688   return nextBoundNode( function, devMapIndex, nodeIndex );
 689}
 690
 691bool ActionMap::nextBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
 692{
 693   // Loop through all of the existing nodes to find the one mapped to the
 694   // given function:
 695   for ( U32 i = devMapIndex; i < mDeviceMaps.size(); i++ )
 696   {
 697      const DeviceMap* dvcMap = mDeviceMaps[i];
 698
 699      for ( U32 j = nodeIndex; j < dvcMap->nodeMap.size(); j++ )
 700      {
 701         const Node* node = &dvcMap->nodeMap[j];
 702         if ( !( node->flags & Node::BindCmd ) && ( dStricmp( function, node->consoleFunction ) == 0 ) )
 703         {
 704            devMapIndex = i;
 705            nodeIndex = j;
 706            return( true );
 707         }
 708      }
 709
 710      nodeIndex = 0;
 711   }
 712
 713   return( false );
 714}
 715
 716//------------------------------------------------------------------------------
 717bool ActionMap::processUnbind(const char *device, const char *action, SimObject* object /*= NULL*/)
 718{
 719   U32 deviceType;
 720   U32 deviceInst;
 721
 722   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
 723      return false;
 724   EventDescriptor eventDescriptor;
 725   if (!createEventDescriptor(action, &eventDescriptor))
 726      return false;
 727
 728   removeNode(deviceType, deviceInst, eventDescriptor.flags,eventDescriptor.eventCode, object);
 729   return true;
 730}
 731
 732//------------------------------------------------------------------------------
 733// This function is for the use of the control remapper.
 734// It will only check against the console function (since all remappable commands are
 735// bound using bind and not bindCmd).
 736//
 737const char* ActionMap::getBinding( const char* command )
 738{
 739   char* returnString = Con::getReturnBuffer( 1024 );
 740   returnString[0] = 0;
 741
 742   char buffer[256];
 743   char deviceBuffer[32];
 744   char keyBuffer[64];
 745 
 746   U32 devMapIndex = 0, nodeIndex = 0;
 747   while ( nextBoundNode( command, devMapIndex, nodeIndex ) )
 748   {
 749      const DeviceMap* deviceMap = mDeviceMaps[devMapIndex];
 750
 751      if ( getDeviceName( deviceMap->deviceType, deviceMap->deviceInst, deviceBuffer ) )
 752      {
 753         const Node* node = &deviceMap->nodeMap[nodeIndex];
 754         const char* modifierString = getModifierString( node->modifiers );
 755
 756         if ( getKeyString( node->action, keyBuffer ) )
 757         {
 758            dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
 759            if ( returnString[0] )
 760               dStrcat( returnString, "\t" );
 761            dStrcat( returnString, buffer );
 762         }
 763      }
 764
 765      ++nodeIndex;
 766   }
 767
 768   return returnString;
 769}
 770
 771//------------------------------------------------------------------------------
 772// This function is for the use of the control remapper.
 773// The intent of this function is to determine if the given event descriptor is already
 774// bound in this action map.  If so, this function returns the command it is bound to.
 775// If not, it returns NULL.
 776//
 777const char* ActionMap::getCommand( const char* device, const char* action )
 778{
 779   U32 deviceType;
 780   U32 deviceInst;
 781   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 782   {
 783      EventDescriptor eventDescriptor;
 784      if ( createEventDescriptor( action, &eventDescriptor ) )
 785      {
 786         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 787         if ( mapNode )
 788         {
 789            if ( mapNode->flags & Node::BindCmd )
 790            {
 791               S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2;
 792               char* returnString = Con::getReturnBuffer( bufferLen );
 793               dSprintf( returnString, bufferLen, "%s\t%s",
 794                     ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ),
 795                     ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) );             
 796               return( returnString );
 797            }              
 798            else
 799               return( mapNode->consoleFunction );             
 800         }
 801      }
 802   }
 803
 804   return( "" );
 805}
 806
 807//------------------------------------------------------------------------------
 808// This function returns whether or not the mapping specified is inverted.
 809// Obviously, this should only be used for axes.
 810bool ActionMap::isInverted( const char* device, const char* action )
 811{
 812   U32 deviceType;
 813   U32 deviceInst;
 814   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 815   {
 816      EventDescriptor eventDescriptor;
 817      if ( createEventDescriptor( action, &eventDescriptor ) )
 818      {
 819         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 820         if ( mapNode )
 821            return( mapNode->flags & Node::Inverted );
 822      }
 823   }
 824
 825   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 826   return( false );
 827}
 828
 829//------------------------------------------------------------------------------
 830F32 ActionMap::getScale( const char* device, const char* action )
 831{
 832   U32 deviceType;
 833   U32 deviceInst;
 834   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 835   {
 836      EventDescriptor eventDescriptor;
 837      if ( createEventDescriptor( action, &eventDescriptor ) )
 838      {
 839         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 840         if ( mapNode )
 841         {
 842            if ( mapNode->flags & Node::HasScale )
 843               return( mapNode->scaleFactor );
 844            else
 845               return( 1.0f );
 846         }
 847      }
 848   }
 849
 850   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 851   return( 1.0f );
 852}
 853
 854//------------------------------------------------------------------------------
 855const char* ActionMap::getDeadZone( const char* device, const char* action )
 856{
 857   U32 deviceType;
 858   U32 deviceInst;
 859   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 860   {
 861      EventDescriptor eventDescriptor;
 862      if ( createEventDescriptor( action, &eventDescriptor ) )
 863      {
 864         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 865         if ( mapNode )
 866         {
 867            if ( mapNode->flags & Node::HasDeadZone )
 868            {
 869               char buf[64];
 870               dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd );
 871               char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
 872               dStrcpy( returnString, buf );
 873               return( returnString );
 874            }
 875            else
 876               return( "0 0" );                    
 877         }
 878      }
 879   }
 880
 881   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 882   return( "" );
 883}
 884
 885//------------------------------------------------------------------------------
 886const char* ActionMap::buildActionString( const InputEventInfo* event )
 887{
 888   const char* modifierString = getModifierString( event->modifier );
 889
 890   char objectBuffer[64];
 891   if ( !getKeyString( event->objInst, objectBuffer ) )
 892      return( "" );
 893
 894   U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2;   
 895   char* returnString = Con::getReturnBuffer( returnLen );
 896   dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer );
 897   return( returnString );
 898}
 899
 900//------------------------------------------------------------------------------
 901bool ActionMap::getDeviceTypeAndInstance(const char *pDeviceName, U32 &deviceType, U32 &deviceInstance)
 902{
 903   U32 offset = 0;
 904   U32 inputMgrDeviceType = 0;
 905
 906   if (dStrnicmp(pDeviceName, "keyboard", dStrlen("keyboard")) == 0) 
 907   {
 908      deviceType      = KeyboardDeviceType;
 909      offset = dStrlen("keyboard");
 910   } 
 911   else if (dStrnicmp(pDeviceName, "mouse", dStrlen("mouse")) == 0) 
 912   {
 913      deviceType      = MouseDeviceType;
 914      offset = dStrlen("mouse");
 915   } 
 916   else if (dStrnicmp(pDeviceName, "joystick", dStrlen("joystick")) == 0) 
 917   {
 918      deviceType      = JoystickDeviceType;
 919      offset = dStrlen("joystick");
 920   }
 921   else if (dStrnicmp(pDeviceName, "gamepad", dStrlen("gamepad")) == 0)
 922   {
 923      deviceType = GamepadDeviceType;
 924      offset     = dStrlen("gamepad");
 925   }
 926   else if(INPUTMGR->isRegisteredDeviceWithAttributes(pDeviceName, inputMgrDeviceType, offset))
 927   {
 928      deviceType = inputMgrDeviceType;
 929   }
 930   else 
 931   {
 932      return false;
 933   }
 934
 935   if (dStrlen(pDeviceName) > offset) 
 936   {
 937      const char* pInst = pDeviceName + offset;
 938      S32 instNum = dAtoi(pInst);
 939      
 940      if (instNum < 0)
 941         deviceInstance = 0;
 942      else   
 943         deviceInstance = instNum;
 944   }
 945   else 
 946   {
 947      deviceInstance = 0;
 948   }
 949
 950   return true;
 951}
 952
 953//------------------------------------------------------------------------------
 954bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer)
 955{
 956   switch (deviceType) {
 957     case KeyboardDeviceType:
 958      dStrcpy(buffer, "keyboard");
 959      break;
 960
 961     case MouseDeviceType:
 962      dSprintf(buffer, 16, "mouse%d", deviceInstance);
 963      break;
 964
 965     case JoystickDeviceType:
 966      dSprintf(buffer, 16, "joystick%d", deviceInstance);
 967      break;
 968
 969     case GamepadDeviceType:
 970      dSprintf(buffer, 16, "gamepad%d", deviceInstance);
 971      break;
 972
 973     default:
 974      {
 975         const char* name = INPUTMGR->getRegisteredDeviceName(deviceType);
 976         if(!name)
 977         {
 978            Con::errorf( "ActionMap::getDeviceName: unknown device type specified, %d (inst: %d)", deviceType, deviceInstance);
 979            return false;
 980         }
 981
 982         dSprintf(buffer, 16, "%s%d", name, deviceInstance);
 983         break;
 984      }
 985   }
 986
 987   return true;
 988}
 989
 990//------------------------------------------------------------------------------
 991const char* ActionMap::getModifierString(const U32 modifiers)
 992{
 993   U32 realModifiers = modifiers;
 994   if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT )
 995      realModifiers |= SI_SHIFT;
 996   if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL )
 997      realModifiers |= SI_CTRL;
 998   if ( modifiers & SI_LALT || modifiers & SI_RALT )
 999      realModifiers |= SI_ALT;
1000   if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT )
1001      realModifiers |= SI_MAC_OPT;
1002
1003   switch (realModifiers & (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT)) 
1004   {
1005#if defined(TORQUE_OS_MAC)
1006      // optional code, to output alt as cmd on mac.
1007      // interpreter sees them as the same...
1008     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1009      return "cmd-shift-ctrl ";
1010
1011     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1012      return "cmd-shift ";
1013
1014     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1015      return "cmd-ctrl ";
1016
1017     case (SI_ALT):
1018      return "cmd ";
1019#else
1020     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1021      return "shift-ctrl-alt ";
1022
1023     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1024      return "shift-alt ";
1025
1026     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1027      return "ctrl-alt ";
1028
1029     case (SI_ALT):
1030      return "alt ";
1031#endif
1032     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL):
1033      return "shift-ctrl ";
1034
1035     case (SI_SHIFT):
1036      return "shift ";
1037
1038     case (SI_CTRL):
1039      return "ctrl ";
1040
1041// plus new mac cases:
1042     case (SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafaaa6c901b729de5fafcdb7b27de39fc7b">SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1043      return "cmd-shift-ctrl-opt ";
1044
1045     case (SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafaaa6c901b729de5fafcdb7b27de39fc7b">SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1046      return "cmd-shift-opt ";
1047
1048     case (SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1049      return "cmd-ctrl-opt ";
1050
1051     case (SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1052      return "cmd-opt ";
1053
1054     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1055      return "shift-ctrl-opt ";
1056
1057     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1058      return "shift-opt ";
1059
1060     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1061      return "ctrl-opt ";
1062
1063     case (SI_MAC_OPT):
1064      return "opt ";
1065      
1066     case 0:
1067      return "";
1068
1069     default:
1070      AssertFatal(false, "Error, should never reach the default case in getModifierString");
1071      return "";
1072   }
1073}
1074
1075//------------------------------------------------------------------------------
1076bool ActionMap::getKeyString(const U32 action, char* buffer)
1077{
1078   U16 asciiCode = 0;
1079
1080   // This is a special case.... numpad keys do have ascii values
1081   // but for the purposes of this method we want to return the 
1082   // description from the gVirtualMap.
1083   if ( !( KEY_NUMPAD0 <= action && action <= KEY_NUMPAD9 ) )
1084      asciiCode = Input::getAscii( action, STATE_LOWER );
1085
1086//   if (action >= KEY_A && action <= KEY_Z) {
1087//      buffer[0] = char(action - KEY_A + 'a');
1088//      buffer[1] = '\0';
1089//      return true;
1090//   } else if (action >= KEY_0 && action <= KEY_9) {
1091//      buffer[0] = char(action - KEY_0 + '0');
1092//      buffer[1] = '\0';
1093   if ( (asciiCode != 0) && dIsDecentChar((char)asciiCode))
1094   {
1095      for (U32 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++) {
1096         if (gAsciiMap[i].asciiCode == asciiCode)
1097         {
1098            dStrcpy(buffer, gAsciiMap[i].pDescription);
1099            return true;
1100         }
1101      }
1102      // Must not have found a string for that ascii code just record the char
1103      buffer[0] = char(asciiCode);
1104      buffer[1] = '\0';
1105      return true;
1106   }
1107   else
1108   {
1109      if (action >= KEY_A && action <= KEY_Z)
1110      {
1111         buffer[0] = char(action - KEY_A + 'a');
1112         buffer[1] = '\0';
1113         return true;
1114      }
1115      else if (action >= KEY_0 && action <= KEY_9) {
1116         buffer[0] = char(action - KEY_0 + '0');
1117         buffer[1] = '\0';
1118         return true;
1119      }
1120      //for (U32 i = 0; gVirtualMap[i].code != 0xFFFFFFFF; i++) {
1121      //   if (gVirtualMap[i].code == action) {
1122      //      dStrcpy(buffer, gVirtualMap[i].pDescription);
1123      //      return true;
1124      //   }
1125      //}
1126      const char* desc = INPUTMGR->findVirtualMapDescFromCode(action);
1127      if(desc)
1128      {
1129         dStrcpy(buffer, desc);
1130         return true;
1131      }
1132   }
1133
1134   Con::errorf( "ActionMap::getKeyString: no string for action %d", action );
1135   return false;
1136}
1137
1138//--------------------------------------------------------------------------
1139bool ActionMap::processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd)
1140{
1141   U32 deviceType;
1142   U32 deviceInst;
1143
1144   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
1145   {
1146      Con::printf("processBindCmd: unknown device: %s", device);
1147      return false;
1148   }
1149
1150   // Ok, we now have the deviceType and instance.  Create an event descriptor
1151   //  for the bind...
1152   //
1153   EventDescriptor eventDescriptor;
1154   if (createEventDescriptor(action, &eventDescriptor) == false) {
1155      Con::printf("Could not create a description for binding: %s", action);
1156      return false;
1157   }
1158
1159   // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually.
1160   if( ( eventDescriptor.eventCode == SI_XAXIS ) ||
1161       ( eventDescriptor.eventCode == SI_YAXIS ) ||
1162       ( eventDescriptor.eventCode == SI_ZAXIS ) ||
1163       ( eventDescriptor.eventCode == SI_RXAXIS ) ||
1164       ( eventDescriptor.eventCode == SI_RYAXIS ) ||
1165       ( eventDescriptor.eventCode == SI_RZAXIS ) ||
1166       ( eventDescriptor.eventCode == SI_SLIDER ) ||
1167       ( eventDescriptor.eventCode == SI_XPOV ) ||
1168       ( eventDescriptor.eventCode == SI_YPOV ) ||
1169       ( eventDescriptor.eventCode == SI_XPOV2 ) ||
1170       ( eventDescriptor.eventCode == SI_YPOV2 ) )
1171   {
1172      Con::warnf( "ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead." );
1173      return false;
1174   }
1175
1176   // Create the full bind entry, and place it in the map
1177   //
1178   // DMMTODO
1179   Node* pBindNode = getNode(deviceType, deviceInst,
1180                             eventDescriptor.flags,
1181                             eventDescriptor.eventCode);
1182
1183   pBindNode->flags           = Node::BindCmd;
1184   pBindNode->deadZoneBegin   = 0;
1185   pBindNode->deadZoneEnd     = 0;
1186   pBindNode->scaleFactor     = 1;
1187
1188   if( pBindNode->makeConsoleCommand )
1189      dFree( pBindNode->makeConsoleCommand );
1190   if( pBindNode->breakConsoleCommand )
1191      dFree( pBindNode->breakConsoleCommand );
1192
1193   if(makeCmd[0])
1194      pBindNode->makeConsoleCommand = dStrdup(makeCmd);
1195   else
1196      pBindNode->makeConsoleCommand = dStrdup("");
1197
1198   if(breakCmd[0])
1199      pBindNode->breakConsoleCommand = dStrdup(breakCmd);
1200   else
1201      pBindNode->breakConsoleCommand = dStrdup("");
1202   return true;
1203}
1204
1205//------------------------------------------------------------------------------
1206bool ActionMap::processBind(const U32 argc, const char** argv, SimObject* object)
1207{
1208   // Ok, the bind will come in the following format:
1209   //  [device] [key or button] <[param spec] [param] ...> [fnName]
1210   //
1211   const char* pDeviceName = argv[0];
1212   const char* pEvent      = argv[1];
1213   const char* pFnName     = argv[argc - 1];
1214
1215   // Determine the device
1216   U32 deviceType;
1217   U32 deviceInst;
1218
1219   if(!getDeviceTypeAndInstance(argv[0], deviceType, deviceInst))
1220   {
1221      Con::printf("processBind: unknown device: %s", pDeviceName);
1222      return false;
1223   }
1224
1225   // Ok, we now have the deviceType and instance.  Create an event descriptor
1226   //  for the bind...
1227   //
1228   EventDescriptor eventDescriptor;
1229   if (createEventDescriptor(pEvent, &eventDescriptor) == false) 
1230   {
1231      Con::printf("Could not create a description for binding: %s", pEvent);
1232      return false;
1233   }
1234
1235   // Event has now been described, and device determined.  we need now to extract
1236   //  any modifiers that the action map will apply to incoming events before
1237   //  calling the bound function...
1238   //
1239   // DMMTODO
1240   U32 assignedFlags = 0;
1241   F32 deadZoneBegin = 0.0f;
1242   F32 deadZoneEnd   = 0.0f;
1243   F32 scaleFactor   = 1.0f;
1244
1245   if (argc != 3) {
1246      // We have the following: "[DSIR]" [deadZone] [scale]
1247      //
1248      const char* pSpec = argv[2];
1249
1250      for (U32 i = 0; pSpec[i] != '\0'; i++) {
1251         switch (pSpec[i]) {
1252           case 'r': case 'R':
1253            assignedFlags |= Node::Ranged;
1254            break;
1255           case 's': case 'S':
1256            assignedFlags |= Node::HasScale;
1257            break;
1258           case 'd': case 'D':
1259            assignedFlags |= Node::HasDeadZone;
1260            break;
1261           case 'i': case 'I':
1262            assignedFlags |= Node::Inverted;
1263            break;
1264           case 'n': case 'N':
1265            assignedFlags |= Node::NonLinear;
1266            break;
1267
1268           default:
1269            AssertFatal(false, avar("Misunderstood specifier in bind (spec string: %s)",
1270                                    pSpec));
1271         }
1272      }
1273
1274      // Ok, we have the flags.  Scan the dead zone and scale, if any.
1275      //
1276      U32 curArg = 3;
1277      if (assignedFlags & Node::HasDeadZone) {
1278         dSscanf(argv[curArg], "%g %g", &deadZoneBegin, &deadZoneEnd);
1279         curArg++;
1280      }
1281      if (assignedFlags & Node::HasScale) {
1282         scaleFactor = dAtof(argv[curArg]);
1283         curArg++;
1284      }
1285
1286      if (curArg != (argc - 1)) {
1287         AssertFatal(curArg == (argc - 1), "error in bind spec somewhere...");
1288         Con::printf("Improperly specified bind for key: %s", argv[2]);
1289         return false;
1290      }
1291   }
1292
1293   // Ensure that the console function is properly specified?
1294   //
1295   // DMMTODO
1296
1297   // Create the full bind entry, and place it in the map
1298   //
1299   // DMMTODO
1300   Node* pBindNode = getNode(deviceType, deviceInst,
1301                             eventDescriptor.flags,
1302                             eventDescriptor.eventCode, object);
1303
1304   pBindNode->flags           = assignedFlags;
1305   pBindNode->deadZoneBegin   = deadZoneBegin;
1306   pBindNode->deadZoneEnd     = deadZoneEnd;
1307   pBindNode->scaleFactor     = scaleFactor;
1308   pBindNode->object          = object;
1309   pBindNode->consoleFunction = StringTable->insert(pFnName);
1310
1311   return true;
1312}
1313
1314//------------------------------------------------------------------------------
1315bool ActionMap::processAction(const InputEventInfo* pEvent)
1316{
1317   // Suppress excluded input events, like alt-tab.
1318   if(Platform::checkKeyboardInputExclusion(pEvent))
1319      return false;
1320
1321   static const char *argv[5];
1322   if (pEvent->action == SI_MAKE) {
1323      const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1324                                   pEvent->modifier,   pEvent->objInst);
1325
1326      if( pNode == NULL )
1327         return false;
1328
1329      // Enter the break into the table if this is a make event...
1330      // Do this now rather than after command is processed because
1331      // command might add a binding which can move the vector of nodes.
1332      enterBreakEvent(pEvent, pNode);
1333
1334      // Whadda ya know, we have this bound.  Set up, and call the console
1335      //  function associated with it...
1336      //
1337      F32 value = pEvent->fValue;
1338      if (pNode->flags & Node::Ranged) {
1339         value = (value * 2.0f) - 1.0f;
1340         if (pNode->flags & Node::Inverted)
1341            value *= -1.0f;
1342      } else {
1343         if (pNode->flags & Node::Inverted)
1344            value = 1.0f - value;
1345      }
1346
1347      if (pNode->flags & Node::HasScale)
1348         value *= pNode->scaleFactor;
1349
1350      if ( pNode->flags & Node::HasDeadZone )
1351      {
1352         if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd ) 
1353            value = 0.0f;
1354         else
1355         {
1356            if( value > 0 )
1357               value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
1358            else
1359               value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
1360         }
1361      }
1362
1363      if( pNode->flags & Node::NonLinear )
1364         value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1365
1366      // Ok, we're all set up, call the function.
1367      if(pNode->flags & Node::BindCmd)
1368      {
1369         // it's a bind command
1370         if(pNode->makeConsoleCommand)
1371            Con::evaluate(pNode->makeConsoleCommand);
1372      }
1373      else if ( pNode->consoleFunction[0] )
1374      {
1375         argv[0] = pNode->consoleFunction;
1376         argv[1] = Con::getFloatArg(value);
1377         if (pNode->object)
1378            Con::executef(pNode->object, argv[0], argv[1]);
1379         else
1380            Con::execute(2, argv);
1381      }
1382      return true;
1383   } else if (pEvent->action == SI_MOVE) {
1384      if (pEvent->deviceType == MouseDeviceType) {
1385         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1386                                      pEvent->modifier,   pEvent->objInst);
1387
1388         if( pNode == NULL )
1389            return false;
1390
1391         // "Do nothing" bind:
1392         if ( !pNode->consoleFunction[0] )
1393            return( true );
1394
1395         // Whadda ya know, we have this bound.  Set up, and call the console
1396         //  function associated with it.  Mouse events ignore range and dead
1397         //  zone params.
1398         //
1399         F32 value = pEvent->fValue;
1400         if (pNode->flags & Node::Inverted)
1401            value *= -1.0f;
1402         if (pNode->flags & Node::HasScale)
1403            value *= pNode->scaleFactor;
1404
1405         // Ok, we're all set up, call the function.
1406         argv[0] = pNode->consoleFunction;
1407         argv[1] = Con::getFloatArg(value);
1408         if (pNode->object)
1409            Con::executef(pNode->object, argv[0], argv[1]);
1410         else
1411            Con::execute(2, argv);
1412
1413         return true;
1414      }
1415      else if ( (pEvent->objType == SI_POS || pEvent->objType == SI_FLOAT || pEvent->objType == SI_ROT || pEvent->objType == SI_INT)
1416                && INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1417              )
1418      {
1419         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1420                                      pEvent->modifier,   pEvent->objInst);
1421
1422         if( pNode == NULL )
1423            return false;
1424
1425         // Ok, we're all set up, call the function.
1426         argv[0] = pNode->consoleFunction;
1427         S32 argc = 1;
1428
1429         if (pEvent->objType == SI_INT)
1430         {
1431            // Handle the integer as some sort of motion such as a
1432            // single component to an absolute position
1433            argv[1] = Con::getIntArg( pEvent->iValue );
1434            argc += 1;
1435         }
1436         else if (pEvent->objType == SI_FLOAT)
1437         {
1438            // Handle float as some sort of motion such as a
1439            // single component to an absolute position
1440            argv[1] = Con::getFloatArg( pEvent->fValue );
1441            argc += 1;
1442         }
1443         else if (pEvent->objType == SI_POS)
1444         {
1445            // Handle Point3F type position
1446            argv[1] = Con::getFloatArg( pEvent->fValue );
1447            argv[2] = Con::getFloatArg( pEvent->fValue2 );
1448            argv[3] = Con::getFloatArg( pEvent->fValue3 );
1449
1450            argc += 3;
1451         }
1452         else
1453         {
1454            // Handle rotation (AngAxisF)
1455            AngAxisF aa(Point3F(pEvent->fValue, pEvent->fValue2, pEvent->fValue3), pEvent->fValue4);
1456            aa.axis.normalize();
1457            argv[1] = Con::getFloatArg( aa.axis.x );
1458            argv[2] = Con::getFloatArg( aa.axis.y );
1459            argv[3] = Con::getFloatArg( aa.axis.z );
1460            argv[4] = Con::getFloatArg( mRadToDeg(aa.angle) );
1461
1462            argc += 4;
1463         }
1464
1465         if (pNode->object)
1466         {
1467            Con::execute(pNode->object, argc, argv);
1468         }
1469         else
1470         {
1471            Con::execute(argc, argv);
1472         }
1473
1474         return true;
1475      }
1476      else if ( pEvent->deviceType == JoystickDeviceType 
1477                || pEvent->deviceType == GamepadDeviceType
1478                || INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1479              )
1480      {
1481         // Joystick events...
1482         const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst,
1483                                       pEvent->modifier,   pEvent->objInst );
1484
1485         if( pNode == NULL )
1486            return false;
1487
1488         // "Do nothing" bind:
1489         if ( !pNode->consoleFunction[0] )
1490            return( true );
1491
1492         // Whadda ya know, we have this bound.  Set up, and call the console
1493         //  function associated with it.  Joystick move events are the same as mouse
1494         //  move events except that they don't ignore dead zone.
1495         //
1496         F32 value = pEvent->fValue;
1497         if ( pNode->flags & Node::Inverted )
1498            value *= -1.0f;
1499
1500         if ( pNode->flags & Node::HasScale )
1501            value *= pNode->scaleFactor;
1502
1503         if ( pNode->flags & Node::HasDeadZone )
1504         {
1505            if ( value >= pNode->deadZoneBegin &&
1506                 value <= pNode->deadZoneEnd )
1507               value = 0.0f;
1508            else
1509            {
1510               if( value > 0 )
1511                  value = ( value - pNode->deadZoneEnd ) * ( 1.f / ( 1.f - pNode->deadZoneEnd ) );
1512               else
1513                  value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f + pNode->deadZoneBegin ) );
1514            }
1515         }
1516
1517         if( pNode->flags & Node::NonLinear )
1518            value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1519
1520         // Ok, we're all set up, call the function.
1521         argv[0] = pNode->consoleFunction;
1522         argv[1] = Con::getFloatArg( value );
1523         if (pNode->object)
1524            Con::executef(pNode->object, argv[0], argv[1]);
1525         else
1526            Con::execute(2, argv);
1527
1528         return true;
1529      }
1530   }
1531   else if (pEvent->action == SI_BREAK)
1532   {
1533      return checkBreakTable(pEvent);
1534   }
1535   else if (pEvent->action == SI_VALUE)
1536   {
1537      if ( (pEvent->objType == SI_FLOAT || pEvent->objType == SI_INT)
1538                && INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1539              )
1540      {
1541         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1542                                      pEvent->modifier,   pEvent->objInst);
1543
1544         if( pNode == NULL )
1545            return false;
1546
1547         // Ok, we're all set up, call the function.
1548         argv[0] = pNode->consoleFunction;
1549         S32 argc = 1;
1550
1551         if (pEvent->objType == SI_INT)
1552         {
1553            // Handle the integer as some sort of motion such as a
1554            // single component to an absolute position
1555            argv[1] = Con::getIntArg( pEvent->iValue );
1556            argc += 1;
1557         }
1558         else if (pEvent->objType == SI_FLOAT)
1559         {
1560            // Handle float as some sort of motion such as a
1561            // single component to an absolute position
1562            argv[1] = Con::getFloatArg( pEvent->fValue );
1563            argc += 1;
1564         }
1565
1566         if (pNode->object)
1567         {
1568            Con::execute(pNode->object, argc, argv);
1569         }
1570         else
1571         {
1572            Con::execute(argc, argv);
1573         }
1574
1575         return true;
1576      }
1577   }
1578
1579   return false;
1580}
1581
1582//------------------------------------------------------------------------------
1583bool ActionMap::isAction( U32 deviceType, U32 deviceInst, U32 modifiers, U32 action )
1584{
1585   return ( findNode( deviceType, deviceInst, modifiers, action ) != NULL );
1586}
1587
1588//------------------------------------------------------------------------------
1589ActionMap* ActionMap::getGlobalMap()
1590{
1591   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1592   AssertFatal( pActionMapSet && pActionMapSet->size() != 0,
1593                "error, no ActiveMapSet or no global action map...");
1594
1595   return ( ( ActionMap* ) pActionMapSet->first() );
1596}
1597
1598//------------------------------------------------------------------------------
1599void ActionMap::enterBreakEvent(const InputEventInfo* pEvent, const Node* pNode)
1600{
1601   // There aren't likely to be many breaks outstanding at any one given time,
1602   //  so a simple linear search is probably sufficient.  Note that the break table
1603   //  is static to the class, all breaks are directed to the action map that received
1604   //  the make.
1605   //
1606   S32 entry = -1;
1607   for (U32 i = 0; i < smBreakTable.size(); i++) {
1608      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
1609          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
1610          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
1611         // Match.
1612         entry = i;
1613         break;
1614      }
1615   }
1616   if (entry == -1) {
1617      smBreakTable.increment();
1618      entry = smBreakTable.size() - 1;
1619
1620      smBreakTable[entry].deviceType = pEvent->deviceType;
1621      smBreakTable[entry].deviceInst = pEvent->deviceInst;
1622      smBreakTable[entry].objInst    = pEvent->objInst;
1623   }
1624
1625   // Ok, we now have the entry, and know that the device desc. and the objInst match.
1626   //  Copy out the node information...
1627   //
1628   smBreakTable[entry].object = pNode->object;
1629   smBreakTable[entry].consoleFunction = pNode->consoleFunction;
1630   if(pNode->breakConsoleCommand)
1631      smBreakTable[entry].breakConsoleCommand = dStrdup(pNode->breakConsoleCommand);
1632   else
1633      smBreakTable[entry].breakConsoleCommand = NULL;
1634
1635   smBreakTable[entry].flags         = pNode->flags;
1636   smBreakTable[entry].deadZoneBegin = pNode->deadZoneBegin;
1637   smBreakTable[entry].deadZoneEnd   = pNode->deadZoneEnd;
1638   smBreakTable[entry].scaleFactor   = pNode->scaleFactor;
1639}
1640
1641//------------------------------------------------------------------------------
1642bool ActionMap::checkBreakTable(const InputEventInfo* pEvent)
1643{
1644   for (U32 i = 0; i < smBreakTable.size(); i++) 
1645   {
1646      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
1647          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
1648          smBreakTable[i].objInst    == U32(pEvent->objInst)) 
1649      {
1650         fireBreakEvent(i, pEvent->fValue);
1651         return true;
1652      }
1653   }
1654
1655   return false;
1656}
1657
1658//------------------------------------------------------------------------------
1659bool ActionMap::handleEvent(const InputEventInfo* pEvent)
1660{
1661   // Interate through the ActionMapSet until we get a map that
1662   //  handles the event or we run out of maps...
1663   //
1664   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1665   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
1666               "error, no ActiveMapSet or no global action map...");
1667               
1668   for (SimSet::iterator itr = pActionMapSet->end() - 1;
1669        itr > pActionMapSet->begin(); itr--) {
1670      ActionMap* pMap = static_cast<ActionMap*>(*itr);
1671      if (pMap->processAction(pEvent) == true)
1672         return true;
1673   }
1674   
1675   // Found no matching action.  Try with the modifiers stripped.
1676
1677   InputEventInfo eventNoModifiers = *pEvent;
1678   eventNoModifiers.modifier = ( InputModifiers ) 0;
1679   
1680   for (SimSet::iterator itr = pActionMapSet->end() - 1;
1681        itr > pActionMapSet->begin(); itr--) {
1682      ActionMap* pMap = static_cast<ActionMap*>(*itr);
1683      if( pMap->processAction( &eventNoModifiers ) )
1684         return true;
1685   }
1686
1687   return false;
1688}
1689
1690//------------------------------------------------------------------------------
1691bool ActionMap::handleEventGlobal(const InputEventInfo* pEvent)
1692{
1693   return getGlobalMap()->processAction( pEvent );
1694}
1695
1696//------------------------------------------------------------------------------
1697bool ActionMap::checkAsciiGlobal( U16 key, U32 modifiers )
1698{
1699   // Does this ascii map to a key?
1700   U16 keyCode = Input::getKeyCode(key);
1701   if(keyCode == 0)
1702      return false;
1703
1704   // Grab the action map set.
1705   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1706   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
1707      "error, no ActiveMapSet or no global action map...");
1708
1709   // Grab the device maps for the first ActionMap.
1710   Vector<DeviceMap*> &maps = ((ActionMap*)pActionMapSet->first())->mDeviceMaps;
1711
1712   // Find the keyboard.
1713   DeviceMap *keyMap = NULL;
1714   for(S32 i=0; i<maps.size(); i++)
1715   {
1716      // CodeReview Doesn't deal with multiple keyboards [bjg, 5/16/07]
1717      if(maps[i]->deviceType == KeyboardDeviceType)
1718      {
1719         keyMap = maps[i];
1720         break;
1721      }
1722   }
1723
1724   if(!keyMap)
1725      return false;
1726
1727   // Normalize modifiers.
1728   U32 realMods = modifiers;
1729   if (realMods & SI_SHIFT)
1730      realMods |= SI_SHIFT;
1731   if (realMods & SI_CTRL)
1732      realMods |= SI_CTRL;
1733   if (realMods & SI_ALT)
1734      realMods |= SI_ALT;
1735   if (realMods & SI_MAC_OPT)
1736      realMods |= SI_MAC_OPT;
1737
1738   // Now find a matching node, if there is one.
1739   for(S32 i=0; i<keyMap->nodeMap.size(); i++)
1740   {
1741      Node &n = keyMap->nodeMap[i];
1742
1743      if(n.action == keyCode && (n.modifiers == modifiers))
1744         return true;
1745   }
1746
1747   return false;
1748}
1749
1750void ActionMap::clearAllBreaks()
1751{
1752   while(smBreakTable.size())
1753      fireBreakEvent(smBreakTable.size()-1);
1754}
1755
1756void ActionMap::fireBreakEvent( U32 i, F32 fValue )
1757{
1758   // Match.  Issue the break event...
1759   //
1760   F32 value = fValue;
1761   if (smBreakTable[i].flags & Node::Ranged) {
1762      value = (value * 2.0f) - 1.0f;
1763      if (smBreakTable[i].flags & Node::Inverted)
1764         value *= -1.0f;
1765   } else {
1766      if (smBreakTable[i].flags & Node::Inverted)
1767         value = 1.0f - value;
1768   }
1769
1770   if (smBreakTable[i].flags & Node::HasScale)
1771      value *= smBreakTable[i].scaleFactor;
1772
1773   if (smBreakTable[i].flags & Node::HasDeadZone)
1774   {
1775      if (value >= smBreakTable[i].deadZoneBegin &&
1776         value <= smBreakTable[i].deadZoneEnd)
1777         value = 0.0f;
1778      else
1779      {
1780         if( value > 0 )
1781            value = ( value - smBreakTable[i].deadZoneBegin ) * ( 1.f / ( 1.f - smBreakTable[i].deadZoneBegin ) );
1782         else
1783            value = ( value + smBreakTable[i].deadZoneBegin ) * ( 1.f / ( 1.f - smBreakTable[i].deadZoneBegin ) );
1784      }
1785   }
1786
1787   if( smBreakTable[i].flags & Node::NonLinear )
1788      value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1789
1790   // Ok, we're all set up, call the function.
1791   if(smBreakTable[i].consoleFunction)
1792   {
1793      if ( smBreakTable[i].consoleFunction[0] )
1794      {
1795         static const char *argv[2];
1796         argv[0] = smBreakTable[i].consoleFunction;
1797         argv[1] = Con::getFloatArg(value);
1798         if (smBreakTable[i].object)
1799            Con::executef(smBreakTable[i].object, argv[0], argv[1]);
1800         else
1801            Con::execute(2, argv);
1802      }
1803   }
1804   else if(smBreakTable[i].breakConsoleCommand)
1805   {
1806      Con::evaluate(smBreakTable[i].breakConsoleCommand);
1807      dFree(smBreakTable[i].breakConsoleCommand);
1808   }
1809   smBreakTable.erase(i);
1810}
1811
1812//------------------------------------------------------------------------------
1813
1814// Console interop version.
1815
1816static ConsoleDocFragment _ActionMapbind1(
1817   "@brief Associates a function to an input event.\n\n"
1818   "When the input event is raised, the specified function will be called.\n\n"
1819   "@param device The input device, such as mouse or keyboard.\n"
1820   "@param action The input event, such as space, button0, etc.\n"
1821   "@param command The function to bind to the action. Function must have a single boolean argument.\n"
1822   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
1823   "@tsexample\n"
1824   "// Simple function that prints to console\n"
1825   "// %val - Sent by the device letting the user know\n"
1826   "// if an input was pressed (true) or released (false)\n"
1827   "function testInput(%val)\n"
1828   "{\n"
1829   "   if(%val)\n"
1830   "    echo(\"Key is down\");\n"
1831   "   else\n"
1832   "    echo(\"Key was released\");\n"
1833   "}\n\n"
1834   "// Bind the \'K\' key to the testInput function\n"
1835   "moveMap.bind(keyboard, k, testInput);\n\n"
1836   "@endtsexample\n\n\n",
1837   "ActionMap",
1838   "bool bind( string device, string action, string command );");
1839
1840static ConsoleDocFragment _ActionMapbind2(
1841   "@brief Associates a function and input parameters to an input event.\n\n"
1842   "When the input event is raised, the specified function will be called. Modifier flags may be specified to process "
1843   "dead zones, input inversion, and more.\n\n"
1844   "Valid modifier flags:\n\n"
1845   " - R - Input is Ranged.\n"
1846   " - S - Input is Scaled.\n"
1847   " - I - Input is inverted.\n"
1848   " - D - Dead zone is present.\n"
1849   " - N - Input should be re-fit to a non-linear scale.\n\n"
1850   "@param device The input device, such as mouse or keyboard.\n"
1851   "@param action The input event, such as space, button0, etc.\n"
1852   "@param flag Modifier flag assigned during binding, letting event know there are additional parameters to consider. \n"
1853   "@param deadZone Restricted region in which device motion will not be acknowledged.\n"
1854   "@param scale Modifies the deadZone region.\n"
1855   "@param command The function bound to the action. Must take in a single argument.\n"
1856   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
1857   "@tsexample\n"
1858   "// Simple function that adjusts the pitch of the camera based on the "
1859   "mouse's movement along the X axis.\n"
1860   "function testPitch(%val)\n"
1861   "{\n"
1862   "   %pitchAdj = getMouseAdjustAmount(%val);\n"
1863   "   $mvPitch += %pitchAdj;\n"
1864   "}\n\n"
1865   "// Bind the mouse's X axis to the testPitch function\n"
1866   "// DI is flagged, meaning input is inverted and has a deadzone\n"
1867   "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n"
1868   "@endtsexample\n\n\n",
1869   "ActionMap",
1870   "bool bind( string device, string action, string flag, string deadZone, string scale, string command );");
1871
1872ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" 
1873           "@hide")
1874{
1875   StringStackWrapper args(argc - 2, argv + 2);
1876   return object->processBind( args.count(), args, NULL );
1877}
1878
1879static ConsoleDocFragment _ActionMapbindObj1(
1880   "@brief Associates a function to an input event for a specified class or object.\n\n"
1881   "You must specify a device, the action to bind, a function, and an object to be called when the event happens. "
1882   "The function specified must be set to receive a single boolean value passed.\n\n"
1883   "@param device The input device, such as mouse or keyboard.\n"
1884   "@param action The input event, such as space, button0, etc.\n"
1885   "@param command The function bound to the action.\n"
1886   "@param object The object or class bound to the action.\n"
1887   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
1888   "@tsexample\n"
1889   "moveMap.bindObj(keyboard, \"numpad1\", \"rangeChange\", %player);"
1890   "@endtsexample\n\n",
1891   "ActionMap",
1892   "bool bindObj( string device, string action, string command, SimObjectID object );");
1893
1894static ConsoleDocFragment _ActionMapbindObj2(
1895   "@brief Associates a function to an input event for a specified class or object.\n\n"
1896   "You must specify a device, the action to bind, a function, and an object to be called when the event happens. "
1897   "The function specified must be set to receive a single boolean value passed. Modifier flags may be specified to process "
1898   "dead zones, input inversion, and more.\n\n"
1899   "Valid modifier flags:\n\n"
1900   " - R - Input is Ranged.\n"
1901   " - S - Input is Scaled.\n"
1902   " - I - Input is inverted.\n"
1903   " - D - Dead zone is present.\n"
1904   " - N - Input should be re-fit to a non-linear scale.\n\n"
1905   "@param device The input device, such as mouse or keyboard.\n"
1906   "@param action The input event, such as space, button0, etc.\n"
1907   "@param flag Modifier flag assigned during binding, letting event know there are additional parameters to consider.\n"
1908   "@param deadZone [Required only when flag is set] Restricted region in which device motion will not be acknowledged.\n"
1909   "@param scale [Required only when flag is set] Modifies the deadZone region.\n"
1910   "@param command The function bound to the action.\n"
1911   "@param object The object or class bound to the action.\n"
1912   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
1913   "@tsexample\n"
1914   "// Bind the mouse's movement along the x-axis to the testInput function of the Player class\n"
1915   "// DSI is flagged, meaning input is inverted, has scale and has a deadzone\n"
1916   "%this.bindObj( mouse, \"xaxis\", \"DSI\", %deadZone, %scale, \"testInput\", %player );\n"
1917   "@endtsexample\n\n\n",
1918   "ActionMap",
1919   "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );");
1920
1921ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec, mod...], command, object)"
1922           "@hide")
1923{
1924   SimObject* simObject = Sim::findObject(argv[argc - 1]);
1925   if ( simObject == NULL )
1926   {
1927      Con::warnf("ActionMap::bindObj() - Cannot bind, specified object was not found!");
1928      return false;
1929   }
1930
1931   StringStackWrapper args(argc - 3, argv + 2);
1932   return object->processBind( args.count(), args, simObject );
1933}
1934
1935//------------------------------------------------------------------------------
1936
1937DefineEngineMethod( ActionMap, bindCmd, bool, ( const char* device, const char* action, const char* makeCmd, const char* breakCmd ), ( "" ),
1938    "@brief Associates a make command and optional break command to a specified input device action.\n\n"
1939    "Must include parenthesis and semicolon in the make and break command strings.\n\n"
1940    "@param device The device to bind to. Can be a keyboard, mouse, joystick or gamepad.\n"
1941    "@param action The device action to bind to. The action is dependant upon the device. Specify a key for keyboards.\n"
1942    "@param makeCmd The command to execute when the device/action is made.\n"
1943    "@param breakCmd [optional] The command to execute when the device or action is unmade.\n"
1944    "@return True the bind was successful, false if the device was unknown or description failed.\n"
1945   "@tsexample\n"
1946   "// Print to the console when the spacebar is pressed\n"
1947   "function onSpaceDown()\n"
1948   "{\n"
1949   "   echo(\"Space bar down!\");\n"
1950   "}\n\n"
1951   "// Print to the console when the spacebar is released\n"
1952   "function onSpaceUp()\n"
1953   "{\n"
1954   "   echo(\"Space bar up!\");\n"
1955   "}\n\n"
1956   "// Bind the commands onSpaceDown() and onSpaceUp() to spacebar events\n\n"
1957   "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n"
1958   "@endtsexample\n\n")
1959{
1960   return object->processBindCmd( device, action, makeCmd, breakCmd );
1961}
1962
1963DefineEngineMethod( ActionMap, unbind, bool, ( const char* device, const char* action ),,
1964   "@brief Removes the binding on an input device and action.\n"
1965   "@param device The device to unbind from. Can be a keyboard, mouse, joystick or a gamepad.\n"
1966   "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n"
1967   "@return True if the unbind was successful, false if the device was unknown or description failed.\n\n"
1968   "@tsexample\n"
1969   "moveMap.unbind(\"keyboard\", \"space\");\n"
1970   "@endtsexample\n\n")
1971{
1972   return object->processUnbind( device, action );
1973}
1974
1975DefineEngineMethod( ActionMap, unbindObj, bool, ( const char* device, const char* action, const char* obj ),,
1976   "@brief Remove any object-binding on an input device and action.\n"
1977   "@param device The device to bind to.  Can be keyboard, mouse, joystick or gamepad.\n"
1978   "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n"
1979   "@param obj The object to perform unbind against.\n"
1980   "@return True if the unbind was successful, false if the device was unknown or description failed.\n"
1981   "@tsexample\n"
1982   "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);"
1983   "@endtsexample\n\n\n")
1984{
1985    SimObject* simObject = Sim::findObject(obj);
1986    if ( simObject == NULL )
1987    {
1988        Con::warnf("ActionMap::unbindObj() - Cannot unbind, specified object was not found!");
1989        return false;
1990    }
1991
1992    return object->processUnbind( device, action, simObject );
1993}
1994
1995DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ), ( NULL, false ),
1996   "@brief Saves the ActionMap to a file or dumps it to the console.\n\n"
1997   "@param fileName The file path to save the ActionMap to. If a filename is not specified "
1998   " the ActionMap will be dumped to the console.\n"
1999   "@param append Whether to write the ActionMap at the end of the file or overwrite it.\n"
2000   "@tsexample\n"
2001   "// Write out the actionmap into the config.cs file\n"
2002   "moveMap.save( \"scripts/client/config.cs\" );"
2003   "@endtsexample\n\n")
2004{
2005   char buffer[1024];
2006
2007   if(fileName)
2008   {
2009      if(Con::expandScriptFilename(buffer, sizeof(buffer), fileName))
2010         fileName = buffer;
2011   }
2012
2013   object->dumpActionMap( fileName, append );
2014}
2015
2016DefineEngineFunction( getCurrentActionMap, ActionMap*, (),,
2017   "@brief Returns the current %ActionMap.\n"
2018   "@see ActionMap"
2019   "@ingroup Input")
2020{
2021   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2022   return dynamic_cast< ActionMap* >( pActionMapSet->last() );
2023}
2024
2025DefineEngineMethod( ActionMap, push, void, (),,
2026   "@brief Push the ActionMap onto the %ActionMap stack.\n\n"
2027   "Activates an ActionMap and placees it at the top of the ActionMap stack.\n\n"
2028   "@tsexample\n"
2029   "// Make moveMap the active action map\n"
2030   "moveMap.push();\n"
2031   "@endtsexample\n\n"
2032   "@see ActionMap")
2033{
2034   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2035   pActionMapSet->pushObject( object );
2036}
2037
2038DefineEngineMethod( ActionMap, pop, void, (),,
2039   "@brief Pop the ActionMap off the %ActionMap stack.\n\n"
2040   "Deactivates an %ActionMap and removes it from the @ActionMap stack.\n"
2041   "@tsexample\n"
2042   "// Deactivate moveMap\n"
2043   "moveMap.pop();\n"
2044   "@endtsexample\n\n"
2045   "@see ActionMap")
2046{
2047   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2048   pActionMapSet->removeObject( object );
2049}
2050
2051DefineEngineMethod( ActionMap, getBinding, const char*, ( const char* command ),,
2052   "@brief Gets the ActionMap binding for the specified command.\n\n"
2053   "Use getField() on the return value to get the device and action of the binding.\n"
2054   "@param command The function to search bindings for.\n"
2055   "@return The binding against the specified command. Returns an empty string(\"\") "
2056   "if a binding wasn't found.\n"
2057   "@tsexample\n"
2058   "// Find what the function \"jump()\" is bound to in moveMap\n"
2059   "%bind = moveMap.getBinding( \"jump\" );\n\n"
2060   "if ( %bind !$= \"\" )\n"
2061   "{\n"
2062   "// Find out what device is used in the binding\n"
2063   "  %device = getField( %bind, 0 );\n\n"
2064   "// Find out what action (such as a key) is used in the binding\n"
2065   "  %action = getField( %bind, 1 );\n"
2066   "}\n"
2067   "@endtsexample\n\n"
2068   "@see getField")
2069{
2070   return object->getBinding( command );  
2071}
2072
2073DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, const char* action ),,
2074   "@brief Gets ActionMap command for the device and action.\n\n"
2075   "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n"
2076   "@param action The device action that was bound.  The action is dependant upon the device. Specify a key for keyboards.\n"
2077   "@return The command against the specified device and action.\n"
2078   "@tsexample\n"
2079   "// Find what function is bound to a device\'s action\n"
2080   "// In this example, \"jump()\" was assigned to the space key in another script\n"
2081   "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n"
2082   "// Should print \"jump\" in the console\n"
2083   "echo(%command)\n"
2084   "@endtsexample\n\n")
2085{
2086   return object->getCommand( device, action ); 
2087}
2088
2089DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const char* action ),,
2090   "@brief Determines if the specified device and action is inverted.\n\n"
2091   "Should only be used for scrolling devices or gamepad/joystick axes."
2092   "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n"
2093   "@param action The device action that was bound.  The action is dependant upon the device. Specify a key for keyboards.\n"
2094   "@return True if the specified device and action is inverted.\n"
2095   "@tsexample\n"
2096   "%if ( moveMap.isInverted( \"mouse\", \"xaxis\"))\n"
2097   "   echo(\"Mouse's xAxis is inverted\");"
2098   "@endtsexample\n\n")
2099{
2100   return object->isInverted( device, action ); 
2101}
2102
2103DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* action ),,
2104   "@brief Get any scaling on the specified device and action.\n\n"
2105   "@param device The device that was bound. Can be keyboard, mouse, joystick or gamepad.\n"
2106   "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n"
2107   "@return Any scaling applied to the specified device and action.\n"
2108   "@tsexample\n"
2109   "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n"
2110   "@endtsexample\n\n")
2111{
2112   return object->getScale( device, action );   
2113}
2114
2115DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, const char* action ),,
2116   "@brief Gets the Dead zone for the specified device and action.\n\n"
2117   "@param device The device that was bound.  Can be a keyboard, mouse, joystick or a gamepad.\n"
2118   "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n"
2119   "@return The dead zone for the specified device and action. Returns \"0 0\" if there is no dead zone " 
2120   "or an empty string(\"\") if the mapping was not found.\n"
2121   "@tsexample\n"
2122   "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n"
2123   "@endtsexample\n\n")
2124{
2125   return object->getDeadZone( device, action );   
2126}
2127
2128//------------------------------------------------------------------------------
2129AsciiMapping gAsciiMap[] =
2130{
2131   //--- KEYBOARD EVENTS
2132   //
2133   { "space",           0x0020 },
2134   //{ "exclamation",     0x0021 },
2135   { "doublequote",     0x0022 },
2136   //{ "pound",           0x0023 },
2137   //{ "ampersand",       0x0026 },
2138   { "apostrophe",      0x0027 },
2139   //{ "lparen",          0x0028 },
2140   //{ "rparen",          0x0029 },
2141   { "comma",           0x002c },
2142   { "minus",           0x002d },
2143   { "period",          0x002e },
2144   //{ "slash",           0x002f },
2145   //{ "colon",           0x003a },
2146   //{ "semicolon",       0x003b },
2147   //{ "lessthan",        0x003c },
2148   //{ "equals",          0x003d },
2149   //{ "morethan",        0x003e },
2150   //{ "lbracket",        0x005b },
2151   { "backslash",       0x005c },
2152   //{ "rbracket",        0x005d },
2153   //{ "circumflex",      0x005e },
2154   //{ "underscore",      0x005f },
2155   { "grave",           0x0060 },
2156   //{ "tilde",           0x007e },
2157   //{ "vertbar",         0x007c },
2158   //{ "exclamdown",      0x00a1 },
2159   //{ "cent",            0x00a2 },
2160   //{ "sterling",        0x00a3 },
2161   //{ "currency",        0x00a4 },
2162   //{ "brokenbar",       0x00a6 },
2163   //{ "ring",            0x00b0 },
2164   //{ "plusminus",       0x00b1 },
2165   { "super2",          0x00b2 },
2166   { "super3",          0x00b3 },
2167   { "acute",           0x00b4 },
2168   //{ "mu",              0x00b5 },
2169   //{ "ordmasculine",    0x00ba },
2170   //{ "questiondown",    0x00bf },
2171   //{ "gemandbls",       0x00df },
2172   //{ "agrave",          0x00e0 },
2173   //{ "aacute",          0x00e1 },
2174   //{ "acircumflex",     0x00e2 },
2175   //{ "atilde",          0x00e3 },
2176   //{ "adieresis",       0x00e4 },
2177   //{ "aring",           0x00e5 },
2178   //{ "ae",              0x00e6 },
2179   //{ "ccedille",        0x00e7 },
2180   //{ "egrave",          0x00e8 },
2181   //{ "eacute",          0x00e9 },
2182   //{ "ecircumflex",     0x00ea },
2183   //{ "edieresis",       0x00eb },
2184   //{ "igrave",          0x00ec },
2185   //{ "iacute",          0x00ed },
2186   //{ "icircumflex",     0x00ee },
2187   //{ "idieresis",       0x00ef },
2188   //{ "ntilde",          0x00f1 },
2189   //{ "ograve",          0x00f2 },
2190   //{ "oacute",          0x00f3 },
2191   //{ "ocircumflex",     0x00f4 },
2192   //{ "otilde",          0x00f5 },
2193   //{ "odieresis",       0x00f6 },
2194   //{ "divide",          0x00f7 },
2195   //{ "oslash",          0x00f8 },
2196   //{ "ugrave",          0x00f9 },
2197   //{ "uacute",          0x00fa },
2198   //{ "ucircumflex",     0x00fb },
2199   //{ "udieresis",       0x00fc },
2200   //{ "ygrave",          0x00fd },
2201   //{ "thorn",           0x00fe },
2202   //{ "ydieresis",       0x00ff },
2203   { "nomatch",         0xFFFF }
2204};
2205