actionMap.cpp

Engine/source/sim/actionMap.cpp

More...

Classes:

Public Defines

define
CONST_E() 2.7182818284590452353602874f

Public Variables

Public Functions

_ActionMapbind1("@brief Associates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single boolean <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single boolean <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> 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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> vehicle it could push <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device and event, " "but different in how the event is interpreted. With  bind, " "you specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, then <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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>" )
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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> make command and optional break command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 , bindContext , void , (const char *device, const char *action, const char *holdFunction, const char *tapFunction, U32 holdTime) , ("", "", "", "", 0) , "actionMap.bindCmd( device, action, holdFunction, tapFunction, holdTime)" )
DefineEngineMethod(ActionMap , bindHold , void , (const char *device, const char *action, const char *holdFunction, bool returnHoldTime) , ("", "", "", false) , "actionMap.bindCmd( device, action, holdFunction, returnHoldTime)" )
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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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) , (nullAsType< const char * >(), false) , "@brief Saves the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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." TORQUE_SCRIPT_EXTENSION " file\n" "moveMap.save( \"scripts/client/config." TORQUE_SCRIPT_EXTENSION "\" );" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )
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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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>" )
DefineEngineStringlyVariadicMethod(ActionMap , bind , bool , 5 , 10 , "actionMap.bind( device, action, [modifier, spec, mod...], command )" "@hide" )
DefineEngineStringlyVariadicMethod(ActionMap , bindObj , bool , 6 , 11 , "(device, action, [modifier, spec, mod...], command, object)" "@hide" )
bool

Detailed Description

Public Defines

CONST_E() 2.7182818284590452353602874f

Public Variables

AsciiMapping gAsciiMap []

Public Functions

_ActionMapbind1("@brief Associates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">argument.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single boolean <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified class or <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "You must specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, the action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single boolean <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> 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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the binding was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> vehicle it could push <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device and event, " "but different in how the event is interpreted. With  bind, " "you specify <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> device, action <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bind, then <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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>" )

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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> make command and optional break command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 , bindContext , void , (const char *device, const char *action, const char *holdFunction, const char *tapFunction, U32 holdTime) , ("", "", "", "", 0) , "actionMap.bindCmd( device, action, holdFunction, tapFunction, holdTime)" )

DefineEngineMethod(ActionMap , bindHold , void , (const char *device, const char *action, const char *holdFunction, bool returnHoldTime) , ("", "", "", false) , "actionMap.bindCmd( device, action, holdFunction, returnHoldTime)" )

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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">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_1a4e4fa7e3399708e0777b5308db01278c">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) , (nullAsType< const char * >(), false) , "@brief Saves the <a href="/coding/class/classactionmap/">ActionMap</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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." TORQUE_SCRIPT_EXTENSION " file\n" "moveMap.save( \"scripts/client/config." TORQUE_SCRIPT_EXTENSION "\" );" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )

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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> keyboard, mouse , joystick or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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 href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</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_1a4e4fa7e3399708e0777b5308db01278c">if</a> the unbind was successful, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">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>" )

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

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

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", 1024 );
 250         iostrm->write( dStrlen( lineBuffer ), lineBuffer );
 251      }
 252
 253      dSprintf(lineBuffer, 1024, "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;
 274            if (rNode.flags & Node::BindCmd)
 275               command = "bindCmd";
 276            else if (rNode.flags & Node::Held)
 277               command = "held";
 278            else
 279               command = "bind";
 280
 281            dSprintf(lineBuffer, 1024, "%s.%s(%s, \"%s%s\"",
 282                                        getName(),
 283                                        command,
 284                                        devbuffer,
 285                                        pModifierString, objectbuffer);
 286
 287            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)) {
 288               char buff[10];
 289               U32 curr = 0;
 290               buff[curr++] = ',';
 291               buff[curr++] = ' ';
 292               if (rNode.flags & Node::HasScale)
 293                  buff[curr++] = 'S';
 294               if (rNode.flags & Node::Ranged)
 295                  buff[curr++] = 'R';
 296               if (rNode.flags & Node::HasDeadZone)
 297                  buff[curr++] = 'D';
 298               if (rNode.flags & Node::Inverted)
 299                  buff[curr++] = 'I';
 300               buff[curr] = '\0';
 301
 302               dStrcat(lineBuffer, buff, 1024);
 303            }
 304
 305            if (rNode.flags & Node::HasDeadZone) {
 306               char buff[64];
 307               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
 308               dStrcat(lineBuffer, buff, 1024);
 309            }
 310
 311            if (rNode.flags & Node::HasScale) {
 312               char buff[64];
 313               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
 314               dStrcat(lineBuffer, buff, 1024);
 315            }
 316
 317            if (rNode.flags & Node::BindCmd) {
 318               if (rNode.makeConsoleCommand) {
 319                  dStrcat(lineBuffer, ", \"", 1024);
 320                  U32 pos = dStrlen(lineBuffer);
 321                  expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
 322                  dStrcat(lineBuffer, "\"", 1024);
 323               } else {
 324                  dStrcat(lineBuffer, ", \"\"", 1024);
 325               }
 326               if (rNode.breakConsoleCommand) {
 327                  dStrcat(lineBuffer, ", \"", 1024);
 328                  U32 pos = dStrlen(lineBuffer);
 329                  expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
 330                  dStrcat(lineBuffer, "\"", 1024);
 331               }
 332               else
 333                  dStrcat(lineBuffer, ", \"\"", 1024);
 334            }
 335            else if (rNode.flags & Node::Held) 
 336            {
 337               dStrcat(lineBuffer, ", ", 1024);
 338               dStrcat(lineBuffer, rNode.consoleFunction, 1024);
 339
 340               dStrcat(lineBuffer, ", ", 1024);
 341               dStrcat(lineBuffer, rNode.contextEvent->mConsoleFunctionHeld, 1024);
 342            } 
 343            else {
 344               dStrcat(lineBuffer, ", ", 1024);
 345               dStrcat(lineBuffer, rNode.consoleFunction, 1024);
 346            }
 347
 348            dStrcat(lineBuffer, ");\n", 1024);
 349            iostrm->write(dStrlen(lineBuffer), lineBuffer);
 350         }
 351      }
 352
 353      delete iostrm;
 354   }
 355   else {
 356      // Dump all the binds to the console...
 357      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
 358         const DeviceMap* pDevMap = mDeviceMaps[i];
 359
 360         char devbuffer[32];
 361         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
 362
 363         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
 364            const Node& rNode = pDevMap->nodeMap[j];
 365
 366            const char* pModifierString = getModifierString(rNode.modifiers);
 367
 368            char keybuffer[64];
 369            if (getKeyString(rNode.action, keybuffer) == false)
 370               continue;
 371
 372            const char* command;
 373            if (rNode.flags & Node::BindCmd)
 374               command = "bindCmd";
 375            else if (rNode.flags & Node::Held)
 376               command = "held";
 377            else
 378               command = "bind";
 379
 380            char finalBuffer[1024];
 381            dSprintf(finalBuffer, 1024, "%s.%s(%s, \"%s%s\"",
 382                                        getName(),
 383                                        command,
 384                                        devbuffer,
 385                                        pModifierString, keybuffer);
 386
 387            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)) {
 388               char buff[10];
 389               U32 curr = 0;
 390               buff[curr++] = ',';
 391               buff[curr++] = ' ';
 392               if (rNode.flags & Node::HasScale)
 393                  buff[curr++] = 'S';
 394               if (rNode.flags & Node::Ranged)
 395                  buff[curr++] = 'R';
 396               if (rNode.flags & Node::HasDeadZone)
 397                  buff[curr++] = 'D';
 398               if (rNode.flags & Node::Inverted)
 399                  buff[curr++] = 'I';
 400               buff[curr] = '\0';
 401
 402               dStrcat(finalBuffer, buff, 1024);
 403            }
 404
 405            if (rNode.flags & Node::HasDeadZone) {
 406               char buff[64];
 407               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
 408               dStrcat(finalBuffer, buff, 1024);
 409            }
 410
 411            if (rNode.flags & Node::HasScale) {
 412               char buff[64];
 413               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
 414               dStrcat(finalBuffer, buff, 1024);
 415            }
 416
 417            if (rNode.flags & Node::BindCmd) {
 418               if (rNode.makeConsoleCommand) {
 419                  dStrcat(finalBuffer, ", \"", 1024);
 420                  dStrcat(finalBuffer, rNode.makeConsoleCommand, 1024);
 421                  dStrcat(finalBuffer, "\"", 1024);
 422               } else {
 423                  dStrcat(finalBuffer, ", \"\"", 1024);
 424               }
 425               if (rNode.breakConsoleCommand) {
 426                  dStrcat(finalBuffer, ", \"", 1024);
 427                  dStrcat(finalBuffer, rNode.breakConsoleCommand, 1024);
 428                  dStrcat(finalBuffer, "\"", 1024);
 429               }
 430               else
 431                  dStrcat(finalBuffer, ", \"\"", 1024);
 432            }
 433            else if (rNode.flags & Node::Held)
 434            {
 435               dStrcat(finalBuffer, ", ", 1024);
 436               dStrcat(finalBuffer, rNode.consoleFunction, 1024);
 437
 438               dStrcat(finalBuffer, ", ", 1024);
 439               dStrcat(finalBuffer, rNode.contextEvent->mConsoleFunctionHeld, 1024);
 440            } 
 441            else {
 442               dStrcat(finalBuffer, ", ", 1024);
 443               dStrcat(finalBuffer, rNode.consoleFunction, 1024);
 444            }
 445
 446            dStrcat(finalBuffer, ");", 1024);
 447            Con::printf(finalBuffer);
 448         }
 449      }
 450   }
 451}
 452
 453//--------------------------------------------------------------------------
 454bool ActionMap::createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor)
 455{
 456   char copyBuffer[256];
 457   dStrcpy(copyBuffer, pEventString, 256);
 458
 459   // Do we have modifiers?
 460   char* pSpace = dStrchr(copyBuffer, ' ');
 461   char* pObjectString;
 462   if (pSpace != NULL) {
 463      // Yes.  Parse them out...
 464      //
 465      pDescriptor->flags = 0;
 466      pObjectString      = pSpace + 1;
 467      pSpace[0]          = '\0';
 468
 469      char* pModifier = dStrtok(copyBuffer, "-");
 470      while (pModifier != NULL) {
 471         if (dStricmp(pModifier, "shift") == 0) {
 472            pDescriptor->flags |= SI_SHIFT;
 473         } else if (dStricmp(pModifier, "ctrl") == 0) {
 474            pDescriptor->flags |= SI_CTRL;
 475         } else if (dStricmp(pModifier, "alt") == 0) {
 476            pDescriptor->flags |= SI_ALT;
 477         } else if (dStricmp(pModifier, "cmd") == 0) {
 478            pDescriptor->flags |= SI_ALT;
 479         } else if (dStricmp(pModifier, "opt") == 0) {
 480            pDescriptor->flags |= SI_MAC_OPT;
 481         }
 482
 483         pModifier = dStrtok(NULL, "-");
 484      }
 485   } else {
 486      // No.
 487      pDescriptor->flags = 0;
 488      pObjectString      = copyBuffer;
 489   }
 490
 491   // Now we need to map the key string to the proper KEY code from event.h
 492   //
 493   AssertFatal(dStrlen(pObjectString) != 0, "Error, no key was specified!");
 494
 495   if (dStrlen(pObjectString) == 1)
 496   {
 497      if (dIsDecentChar(*pObjectString)) // includes foreign chars
 498      {
 499         U16 asciiCode = (*pObjectString);
 500         // clear out the FF in upper 8bits for foreign keys??
 501         asciiCode &= 0xFF;
 502         U16 keyCode = Input::getKeyCode(asciiCode);
 503         if ( keyCode >= KEY_0 )
 504         {
 505            pDescriptor->eventType = SI_KEY;
 506            pDescriptor->eventCode = keyCode;
 507            return true;
 508         }
 509         else if (dIsalpha(*pObjectString) == true)
 510         {
 511            pDescriptor->eventType = SI_KEY;
 512            pDescriptor->eventCode = KEY_A+dTolower(*pObjectString)-'a';
 513            return true;
 514         }
 515         else if (dIsdigit(*pObjectString) == true)
 516         {
 517            pDescriptor->eventType = SI_KEY;
 518            pDescriptor->eventCode = KEY_0+(*pObjectString)-'0';
 519            return true;
 520         }
 521      }
 522      return false;
 523   }
 524   else
 525   {
 526      pDescriptor->eventCode = 0;
 527      // Gotta search through the Ascii table...
 528      for (U16 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++)
 529      {
 530         if (dStricmp(pObjectString, gAsciiMap[i].pDescription) == 0)
 531         {
 532            U16 asciiCode = gAsciiMap[i].asciiCode;
 533            U16 keyCode   = Input::getKeyCode(asciiCode);
 534            if ( keyCode >= KEY_0 )
 535            {
 536               pDescriptor->eventType = SI_KEY;
 537               pDescriptor->eventCode = keyCode;
 538               return(true);
 539
 540            }
 541            else
 542            {
 543               break;
 544            }
 545         }
 546      }
 547      // Didn't find an ascii match. Check the virtual map table
 548      //for (U32 j = 0; gVirtualMap[j].code != 0xFFFFFFFF; j++)
 549      //{
 550      //   if (dStricmp(pObjectString, gVirtualMap[j].pDescription) == 0)
 551      //   {
 552      //      pDescriptor->eventType = gVirtualMap[j].type;
 553      //      pDescriptor->eventCode = gVirtualMap[j].code;
 554      //      return true;
 555      //   }
 556      //}
 557      InputEventManager::VirtualMapData* data = INPUTMGR->findVirtualMap(pObjectString);
 558      if(data)
 559      {
 560         pDescriptor->eventType = data->type;
 561         pDescriptor->eventCode = data->code;
 562         return true;
 563      }
 564   }
 565   return false;
 566}
 567
 568//------------------------------------------------------------------------------
 569ActionMap::Node* ActionMap::getNode(const U32 inDeviceType, const U32 inDeviceInst,
 570                   const U32 inModifiers,  const U32 inAction,SimObject* object /*= NULL*/)
 571{
 572   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 573   //
 574   DeviceMap* pDeviceMap = NULL;
 575   U32 i;
 576   for (i = 0; i < mDeviceMaps.size(); i++) 
 577   {
 578      if (mDeviceMaps[i]->deviceType == inDeviceType &&
 579          mDeviceMaps[i]->deviceInst == inDeviceInst) {
 580         pDeviceMap = mDeviceMaps[i];
 581         break;
 582      }
 583   }
 584   if (pDeviceMap == NULL) 
 585   {
 586      mDeviceMaps.increment();
 587      mDeviceMaps.last() = new DeviceMap;
 588      pDeviceMap = mDeviceMaps.last();
 589
 590      pDeviceMap->deviceInst = inDeviceInst;
 591      pDeviceMap->deviceType = inDeviceType;
 592   }
 593
 594   for (i = 0; i < pDeviceMap->nodeMap.size(); i++) 
 595   {
 596      if (pDeviceMap->nodeMap[i].modifiers == inModifiers &&
 597          pDeviceMap->nodeMap[i].action    == inAction &&
 598          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) // Check for an object match if the object exists 
 599      {
 600         return &pDeviceMap->nodeMap[i];
 601      }
 602   }
 603
 604   // If we're here, the node doesn't exist.  create it.
 605   pDeviceMap->nodeMap.increment();
 606
 607   Node* pRetNode = &pDeviceMap->nodeMap.last();
 608   pRetNode->modifiers = inModifiers;
 609   pRetNode->action    = inAction;
 610
 611   pRetNode->flags         = 0;
 612   pRetNode->deadZoneBegin = 0.0;
 613   pRetNode->deadZoneEnd   = 0.0;
 614   pRetNode->scaleFactor   = 1.0;
 615
 616   pRetNode->consoleFunction = NULL;
 617   pRetNode->makeConsoleCommand = NULL;
 618   pRetNode->breakConsoleCommand = NULL;
 619
 620   //[neob, 5/7/2007 - #2975]
 621   pRetNode->object = 0;
 622
 623   return pRetNode;
 624}
 625
 626//------------------------------------------------------------------------------
 627void ActionMap::removeNode(const U32 inDeviceType, const U32 inDeviceInst, const U32 inModifiers, const U32 inAction, SimObject* object /*= NULL*/)
 628{
 629   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 630   //
 631   DeviceMap* pDeviceMap = NULL;
 632   U32 i;
 633   for (i = 0; i < mDeviceMaps.size(); i++) {
 634      if (mDeviceMaps[i]->deviceType == inDeviceType &&
 635          mDeviceMaps[i]->deviceInst == inDeviceInst) {
 636         pDeviceMap = mDeviceMaps[i];
 637         break;
 638      }
 639   }
 640
 641   if (pDeviceMap == NULL)
 642      return;
 643
 644   U32 realMods = inModifiers;
 645   if (realMods & SI_SHIFT)
 646      realMods |= SI_SHIFT;
 647   if (realMods & SI_CTRL)
 648      realMods |= SI_CTRL;
 649   if (realMods & SI_ALT)
 650      realMods |= SI_ALT;
 651   if (realMods & SI_MAC_OPT)
 652      realMods |= SI_MAC_OPT;
 653
 654   for (i = 0; i < pDeviceMap->nodeMap.size(); i++) {
 655      if (pDeviceMap->nodeMap[i].modifiers == realMods &&
 656          pDeviceMap->nodeMap[i].action    == inAction &&
 657          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) 
 658      {
 659          dFree(pDeviceMap->nodeMap[i].makeConsoleCommand);
 660          dFree(pDeviceMap->nodeMap[i].breakConsoleCommand);
 661          pDeviceMap->nodeMap.erase(i);
 662      }
 663   }
 664}
 665
 666//------------------------------------------------------------------------------
 667const ActionMap::Node* ActionMap::findNode(const U32 inDeviceType, const U32 inDeviceInst,
 668                    const U32 inModifiers,  const U32 inAction)
 669{
 670   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
 671   //
 672   DeviceMap* pDeviceMap = NULL;
 673   U32 i;
 674   for (i = 0; i < mDeviceMaps.size(); i++)
 675   {
 676      if (mDeviceMaps[i]->deviceType == inDeviceType && mDeviceMaps[i]->deviceInst == inDeviceInst)
 677      {
 678         pDeviceMap = mDeviceMaps[i];
 679         break;
 680      }
 681   }
 682
 683   if (pDeviceMap == NULL)
 684      return NULL;
 685
 686   U32 realMods = inModifiers;
 687   if (realMods & SI_SHIFT)
 688      realMods |= SI_SHIFT;
 689   if (realMods & SI_CTRL)
 690      realMods |= SI_CTRL;
 691   if (realMods & SI_ALT)
 692      realMods |= SI_ALT;
 693   if (realMods & SI_MAC_OPT)
 694      realMods |= SI_MAC_OPT;
 695
 696   for (i = 0; i < pDeviceMap->nodeMap.size(); i++)
 697   {
 698      // Special case for an ANYKEY bind...
 699      if (pDeviceMap->nodeMap[i].action == KEY_ANYKEY 
 700         && pDeviceMap->nodeMap[i].modifiers == realMods 
 701         && dIsDecentChar(inAction)
 702         && inAction <= U8_MAX)
 703         return &pDeviceMap->nodeMap[i];
 704
 705      if (pDeviceMap->nodeMap[i].modifiers == realMods 
 706         && pDeviceMap->nodeMap[i].action == inAction)
 707         return &pDeviceMap->nodeMap[i];
 708   }
 709
 710   return NULL;
 711}
 712
 713//------------------------------------------------------------------------------
 714bool ActionMap::findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
 715{
 716   devMapIndex = 0;
 717   nodeIndex = 0;
 718   return nextBoundNode( function, devMapIndex, nodeIndex );
 719}
 720
 721bool ActionMap::nextBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
 722{
 723   // Loop through all of the existing nodes to find the one mapped to the
 724   // given function:
 725   for ( U32 i = devMapIndex; i < mDeviceMaps.size(); i++ )
 726   {
 727      const DeviceMap* dvcMap = mDeviceMaps[i];
 728
 729      for ( U32 j = nodeIndex; j < dvcMap->nodeMap.size(); j++ )
 730      {
 731         const Node* node = &dvcMap->nodeMap[j];
 732         if ( !( node->flags & Node::BindCmd ) && ( dStricmp( function, node->consoleFunction ) == 0 ) )
 733         {
 734            devMapIndex = i;
 735            nodeIndex = j;
 736            return( true );
 737         }
 738      }
 739
 740      nodeIndex = 0;
 741   }
 742
 743   return( false );
 744}
 745
 746//------------------------------------------------------------------------------
 747bool ActionMap::processUnbind(const char *device, const char *action, SimObject* object /*= NULL*/)
 748{
 749   U32 deviceType;
 750   U32 deviceInst;
 751
 752   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
 753      return false;
 754   EventDescriptor eventDescriptor;
 755   if (!createEventDescriptor(action, &eventDescriptor))
 756      return false;
 757
 758   removeNode(deviceType, deviceInst, eventDescriptor.flags,eventDescriptor.eventCode, object);
 759   return true;
 760}
 761
 762//------------------------------------------------------------------------------
 763// This function is for the use of the control remapper.
 764// It will only check against the console function (since all remappable commands are
 765// bound using bind and not bindCmd).
 766//
 767const char* ActionMap::getBinding( const char* command )
 768{
 769   char* returnString = Con::getReturnBuffer( 1024 );
 770   returnString[0] = 0;
 771
 772   char buffer[256];
 773   char deviceBuffer[32];
 774   char keyBuffer[64];
 775 
 776   U32 devMapIndex = 0, nodeIndex = 0;
 777   while ( nextBoundNode( command, devMapIndex, nodeIndex ) )
 778   {
 779      const DeviceMap* deviceMap = mDeviceMaps[devMapIndex];
 780
 781      if ( getDeviceName( deviceMap->deviceType, deviceMap->deviceInst, deviceBuffer ) )
 782      {
 783         const Node* node = &deviceMap->nodeMap[nodeIndex];
 784         const char* modifierString = getModifierString( node->modifiers );
 785
 786         if ( getKeyString( node->action, keyBuffer ) )
 787         {
 788            dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
 789            if ( returnString[0] )
 790               dStrcat( returnString, "\t", 1024 );
 791            dStrcat( returnString, buffer, 1024 );
 792         }
 793      }
 794
 795      ++nodeIndex;
 796   }
 797
 798   return returnString;
 799}
 800
 801//------------------------------------------------------------------------------
 802// This function is for the use of the control remapper.
 803// The intent of this function is to determine if the given event descriptor is already
 804// bound in this action map.  If so, this function returns the command it is bound to.
 805// If not, it returns NULL.
 806//
 807const char* ActionMap::getCommand( const char* device, const char* action )
 808{
 809   U32 deviceType;
 810   U32 deviceInst;
 811   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 812   {
 813      EventDescriptor eventDescriptor;
 814      if ( createEventDescriptor( action, &eventDescriptor ) )
 815      {
 816         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 817         if ( mapNode )
 818         {
 819            if ( mapNode->flags & Node::BindCmd )
 820            {
 821               S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2;
 822               char* returnString = Con::getReturnBuffer( bufferLen );
 823               dSprintf( returnString, bufferLen, "%s\t%s",
 824                     ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ),
 825                     ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) );             
 826               return( returnString );
 827            }              
 828            if (mapNode->flags & Node::Held)
 829            {
 830               S32 bufferLen = dStrlen(mapNode->consoleFunction) + dStrlen(mapNode->contextEvent->mConsoleFunctionHeld) + 2;
 831               char* returnString = Con::getReturnBuffer(bufferLen);
 832
 833               dSprintf(returnString, bufferLen, "%st%s",
 834                  (mapNode->consoleFunction ? mapNode->consoleFunction : ""),
 835                  (mapNode->contextEvent->mConsoleFunctionHeld ? mapNode->contextEvent->mConsoleFunctionHeld : ""));
 836
 837               return(returnString);
 838            }
 839            else
 840               return( mapNode->consoleFunction );             
 841         }
 842      }
 843   }
 844
 845   return( "" );
 846}
 847
 848//------------------------------------------------------------------------------
 849// This function returns whether or not the mapping specified is inverted.
 850// Obviously, this should only be used for axes.
 851bool ActionMap::isInverted( const char* device, const char* action )
 852{
 853   U32 deviceType;
 854   U32 deviceInst;
 855   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 856   {
 857      EventDescriptor eventDescriptor;
 858      if ( createEventDescriptor( action, &eventDescriptor ) )
 859      {
 860         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 861         if ( mapNode )
 862            return( mapNode->flags & Node::Inverted );
 863      }
 864   }
 865
 866   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 867   return( false );
 868}
 869
 870//------------------------------------------------------------------------------
 871F32 ActionMap::getScale( const char* device, const char* action )
 872{
 873   U32 deviceType;
 874   U32 deviceInst;
 875   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 876   {
 877      EventDescriptor eventDescriptor;
 878      if ( createEventDescriptor( action, &eventDescriptor ) )
 879      {
 880         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 881         if ( mapNode )
 882         {
 883            if ( mapNode->flags & Node::HasScale )
 884               return( mapNode->scaleFactor );
 885            else
 886               return( 1.0f );
 887         }
 888      }
 889   }
 890
 891   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 892   return( 1.0f );
 893}
 894
 895//------------------------------------------------------------------------------
 896const char* ActionMap::getDeadZone( const char* device, const char* action )
 897{
 898   U32 deviceType;
 899   U32 deviceInst;
 900   if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
 901   {
 902      EventDescriptor eventDescriptor;
 903      if ( createEventDescriptor( action, &eventDescriptor ) )
 904      {
 905         const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
 906         if ( mapNode )
 907         {
 908            if ( mapNode->flags & Node::HasDeadZone )
 909            {
 910               char buf[64];
 911               dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd );
 912               dsize_t returnLen = dStrlen(buf) + 1;
 913               char* returnString = Con::getReturnBuffer( returnLen );
 914               dStrcpy( returnString, buf, returnLen );
 915               return( returnString );
 916            }
 917            else
 918               return( "0 0" );                    
 919         }
 920      }
 921   }
 922
 923   Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
 924   return( "" );
 925}
 926
 927//------------------------------------------------------------------------------
 928const char* ActionMap::buildActionString( const InputEventInfo* event )
 929{
 930   const char* modifierString = getModifierString( event->modifier );
 931
 932   char objectBuffer[64];
 933   if ( !getKeyString( event->objInst, objectBuffer ) )
 934      return( "" );
 935
 936   U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2;   
 937   char* returnString = Con::getReturnBuffer( returnLen );
 938   dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer );
 939   return( returnString );
 940}
 941
 942//------------------------------------------------------------------------------
 943bool ActionMap::getDeviceTypeAndInstance(const char *pDeviceName, U32 &deviceType, U32 &deviceInstance)
 944{
 945   U32 offset = 0;
 946   U32 inputMgrDeviceType = 0;
 947
 948   if (dStrnicmp(pDeviceName, "keyboard", dStrlen("keyboard")) == 0) 
 949   {
 950      deviceType      = KeyboardDeviceType;
 951      offset = dStrlen("keyboard");
 952   } 
 953   else if (dStrnicmp(pDeviceName, "mouse", dStrlen("mouse")) == 0) 
 954   {
 955      deviceType      = MouseDeviceType;
 956      offset = dStrlen("mouse");
 957   } 
 958   else if (dStrnicmp(pDeviceName, "joystick", dStrlen("joystick")) == 0) 
 959   {
 960      deviceType      = JoystickDeviceType;
 961      offset = dStrlen("joystick");
 962   }
 963   else if (dStrnicmp(pDeviceName, "gamepad", dStrlen("gamepad")) == 0)
 964   {
 965      deviceType = GamepadDeviceType;
 966      offset     = dStrlen("gamepad");
 967   }
 968   else if(INPUTMGR->isRegisteredDeviceWithAttributes(pDeviceName, inputMgrDeviceType, offset))
 969   {
 970      deviceType = inputMgrDeviceType;
 971   }
 972   else 
 973   {
 974      return false;
 975   }
 976
 977   if (dStrlen(pDeviceName) > offset) 
 978   {
 979      const char* pInst = pDeviceName + offset;
 980      S32 instNum = dAtoi(pInst);
 981      
 982      if (instNum < 0)
 983         deviceInstance = 0;
 984      else   
 985         deviceInstance = instNum;
 986   }
 987   else 
 988   {
 989      deviceInstance = 0;
 990   }
 991
 992   return true;
 993}
 994
 995//------------------------------------------------------------------------------
 996bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer)
 997{
 998   switch (deviceType) {
 999     case KeyboardDeviceType:
1000      dStrcpy(buffer, "keyboard", 16);
1001      break;
1002
1003     case MouseDeviceType:
1004      dSprintf(buffer, 16, "mouse%d", deviceInstance);
1005      break;
1006
1007     case JoystickDeviceType:
1008      dSprintf(buffer, 16, "joystick%d", deviceInstance);
1009      break;
1010
1011     case GamepadDeviceType:
1012      dSprintf(buffer, 16, "gamepad%d", deviceInstance);
1013      break;
1014
1015     default:
1016      {
1017         const char* name = INPUTMGR->getRegisteredDeviceName(deviceType);
1018         if(!name)
1019         {
1020            Con::errorf( "ActionMap::getDeviceName: unknown device type specified, %d (inst: %d)", deviceType, deviceInstance);
1021            return false;
1022         }
1023
1024         dSprintf(buffer, 16, "%s%d", name, deviceInstance);
1025         break;
1026      }
1027   }
1028
1029   return true;
1030}
1031
1032//------------------------------------------------------------------------------
1033const char* ActionMap::getModifierString(const U32 modifiers)
1034{
1035   U32 realModifiers = modifiers;
1036   if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT )
1037      realModifiers |= SI_SHIFT;
1038   if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL )
1039      realModifiers |= SI_CTRL;
1040   if ( modifiers & SI_LALT || modifiers & SI_RALT )
1041      realModifiers |= SI_ALT;
1042   if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT )
1043      realModifiers |= SI_MAC_OPT;
1044
1045   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)) 
1046   {
1047#if defined(TORQUE_OS_MAC)
1048      // optional code, to output alt as cmd on mac.
1049      // interpreter sees them as the same...
1050     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):
1051      return "cmd-shift-ctrl ";
1052
1053     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1054      return "cmd-shift ";
1055
1056     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1057      return "cmd-ctrl ";
1058
1059     case (SI_ALT):
1060      return "cmd ";
1061#else
1062     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):
1063      return "shift-ctrl-alt ";
1064
1065     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1066      return "shift-alt ";
1067
1068     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafa1b286029c21d6a525f8a8769a40cdba5">SI_ALT):
1069      return "ctrl-alt ";
1070
1071     case (SI_ALT):
1072      return "alt ";
1073#endif
1074     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72faface0fd0652b0c89d58c7c0e89e613b070">SI_CTRL):
1075      return "shift-ctrl ";
1076
1077     case (SI_SHIFT):
1078      return "shift ";
1079
1080     case (SI_CTRL):
1081      return "ctrl ";
1082
1083// plus new mac cases:
1084     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):
1085      return "cmd-shift-ctrl-opt ";
1086
1087     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):
1088      return "cmd-shift-opt ";
1089
1090     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):
1091      return "cmd-ctrl-opt ";
1092
1093     case (SI_ALT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1094      return "cmd-opt ";
1095
1096     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):
1097      return "shift-ctrl-opt ";
1098
1099     case (SI_SHIFT</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1100      return "shift-opt ";
1101
1102     case (SI_CTRL</a>|<a href="/coding/group/group__input__constants/#group__input__constants_1ggae87906764558c3f3650510499da72fafac39046db31b66baa3a5ccc0776813ea2">SI_MAC_OPT):
1103      return "ctrl-opt ";
1104
1105     case (SI_MAC_OPT):
1106      return "opt ";
1107      
1108     case 0:
1109      return "";
1110
1111     default:
1112      AssertFatal(false, "Error, should never reach the default case in getModifierString");
1113      return "";
1114   }
1115}
1116
1117//------------------------------------------------------------------------------
1118bool ActionMap::getKeyString(const U32 action, char* buffer)
1119{
1120   U16 asciiCode = 0;
1121
1122   // This is a special case.... numpad keys do have ascii values
1123   // but for the purposes of this method we want to return the 
1124   // description from the gVirtualMap.
1125   if ( !( KEY_NUMPAD0 <= action && action <= KEY_NUMPAD9 ) )
1126      asciiCode = Input::getAscii( action, STATE_LOWER );
1127
1128//   if (action >= KEY_A && action <= KEY_Z) {
1129//      buffer[0] = char(action - KEY_A + 'a');
1130//      buffer[1] = '\0';
1131//      return true;
1132//   } else if (action >= KEY_0 && action <= KEY_9) {
1133//      buffer[0] = char(action - KEY_0 + '0');
1134//      buffer[1] = '\0';
1135   if ( (asciiCode != 0) && dIsDecentChar((char)asciiCode))
1136   {
1137      for (U32 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++) {
1138         if (gAsciiMap[i].asciiCode == asciiCode)
1139         {
1140            dStrcpy(buffer, gAsciiMap[i].pDescription, 16);
1141            return true;
1142         }
1143      }
1144      // Must not have found a string for that ascii code just record the char
1145      buffer[0] = char(asciiCode);
1146      buffer[1] = '\0';
1147      return true;
1148   }
1149   else
1150   {
1151      if (action >= KEY_A && action <= KEY_Z)
1152      {
1153         buffer[0] = char(action - KEY_A + 'a');
1154         buffer[1] = '\0';
1155         return true;
1156      }
1157      else if (action >= KEY_0 && action <= KEY_9) {
1158         buffer[0] = char(action - KEY_0 + '0');
1159         buffer[1] = '\0';
1160         return true;
1161      }
1162      //for (U32 i = 0; gVirtualMap[i].code != 0xFFFFFFFF; i++) {
1163      //   if (gVirtualMap[i].code == action) {
1164      //      dStrcpy(buffer, gVirtualMap[i].pDescription, 16);
1165      //      return true;
1166      //   }
1167      //}
1168      const char* desc = INPUTMGR->findVirtualMapDescFromCode(action);
1169      if(desc)
1170      {
1171         dStrcpy(buffer, desc, 16);
1172         return true;
1173      }
1174   }
1175
1176   Con::errorf( "ActionMap::getKeyString: no string for action %d", action );
1177   return false;
1178}
1179
1180//--------------------------------------------------------------------------
1181bool ActionMap::processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd)
1182{
1183   U32 deviceType;
1184   U32 deviceInst;
1185
1186   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
1187   {
1188      Con::printf("processBindCmd: unknown device: %s", device);
1189      return false;
1190   }
1191
1192   // Ok, we now have the deviceType and instance.  Create an event descriptor
1193   //  for the bind...
1194   //
1195   EventDescriptor eventDescriptor;
1196   if (createEventDescriptor(action, &eventDescriptor) == false) {
1197      Con::printf("Could not create a description for binding: %s", action);
1198      return false;
1199   }
1200
1201   // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually.
1202   if( ( eventDescriptor.eventCode == SI_XAXIS ) ||
1203       ( eventDescriptor.eventCode == SI_YAXIS ) ||
1204       ( eventDescriptor.eventCode == SI_ZAXIS ) ||
1205       ( eventDescriptor.eventCode == SI_RXAXIS ) ||
1206       ( eventDescriptor.eventCode == SI_RYAXIS ) ||
1207       ( eventDescriptor.eventCode == SI_RZAXIS ) ||
1208       ( eventDescriptor.eventCode == SI_SLIDER ) ||
1209       ( eventDescriptor.eventCode == SI_XPOV ) ||
1210       ( eventDescriptor.eventCode == SI_YPOV ) ||
1211       ( eventDescriptor.eventCode == SI_XPOV2 ) ||
1212       ( eventDescriptor.eventCode == SI_YPOV2 ) )
1213   {
1214      Con::warnf( "ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead." );
1215      return false;
1216   }
1217
1218   // Create the full bind entry, and place it in the map
1219   //
1220   // DMMTODO
1221   Node* pBindNode = getNode(deviceType, deviceInst,
1222                             eventDescriptor.flags,
1223                             eventDescriptor.eventCode);
1224
1225   pBindNode->flags           = Node::BindCmd;
1226   pBindNode->deadZoneBegin   = 0;
1227   pBindNode->deadZoneEnd     = 0;
1228   pBindNode->scaleFactor     = 1;
1229
1230   if( pBindNode->makeConsoleCommand )
1231      dFree( pBindNode->makeConsoleCommand );
1232   if( pBindNode->breakConsoleCommand )
1233      dFree( pBindNode->breakConsoleCommand );
1234
1235   if(makeCmd[0])
1236      pBindNode->makeConsoleCommand = dStrdup(makeCmd);
1237   else
1238      pBindNode->makeConsoleCommand = dStrdup("");
1239
1240   if(breakCmd[0])
1241      pBindNode->breakConsoleCommand = dStrdup(breakCmd);
1242   else
1243      pBindNode->breakConsoleCommand = dStrdup("");
1244   return true;
1245}
1246
1247//------------------------------------------------------------------------------
1248bool ActionMap::processBind(const U32 argc, const char** argv, SimObject* object)
1249{
1250   // Ok, the bind will come in the following format:
1251   //  [device] [key or button] <[param spec] [param] ...> [fnName]
1252   //
1253   const char* pDeviceName = argv[0];
1254   const char* pEvent      = argv[1];
1255   const char* pFnName     = argv[argc - 1];
1256
1257   // Determine the device
1258   U32 deviceType;
1259   U32 deviceInst;
1260
1261   if(!getDeviceTypeAndInstance(argv[0], deviceType, deviceInst))
1262   {
1263      Con::printf("processBind: unknown device: %s", pDeviceName);
1264      return false;
1265   }
1266
1267   // Ok, we now have the deviceType and instance.  Create an event descriptor
1268   //  for the bind...
1269   //
1270   EventDescriptor eventDescriptor;
1271   if (createEventDescriptor(pEvent, &eventDescriptor) == false) 
1272   {
1273      Con::printf("Could not create a description for binding: %s", pEvent);
1274      return false;
1275   }
1276
1277   // Event has now been described, and device determined.  we need now to extract
1278   //  any modifiers that the action map will apply to incoming events before
1279   //  calling the bound function...
1280   //
1281   // DMMTODO
1282   U32 assignedFlags = 0;
1283   F32 deadZoneBegin = 0.0f;
1284   F32 deadZoneEnd   = 0.0f;
1285   F32 scaleFactor   = 1.0f;
1286
1287   if (argc != 3) {
1288      // We have the following: "[DSIR]" [deadZone] [scale]
1289      //
1290      const char* pSpec = argv[2];
1291
1292      for (U32 i = 0; pSpec[i] != '\0'; i++) {
1293         switch (pSpec[i]) {
1294           case 'r': case 'R':
1295            assignedFlags |= Node::Ranged;
1296            break;
1297           case 's': case 'S':
1298            assignedFlags |= Node::HasScale;
1299            break;
1300           case 'd': case 'D':
1301            assignedFlags |= Node::HasDeadZone;
1302            break;
1303           case 'i': case 'I':
1304            assignedFlags |= Node::Inverted;
1305            break;
1306           case 'n': case 'N':
1307            assignedFlags |= Node::NonLinear;
1308            break;
1309
1310           default:
1311            AssertFatal(false, avar("Misunderstood specifier in bind (spec string: %s)",
1312                                    pSpec));
1313         }
1314      }
1315
1316      // Ok, we have the flags.  Scan the dead zone and scale, if any.
1317      //
1318      U32 curArg = 3;
1319      if (assignedFlags & Node::HasDeadZone) {
1320         dSscanf(argv[curArg], "%g %g", &deadZoneBegin, &deadZoneEnd);
1321         curArg++;
1322      }
1323      if (assignedFlags & Node::HasScale) {
1324         scaleFactor = dAtof(argv[curArg]);
1325         curArg++;
1326      }
1327
1328      if (curArg != (argc - 1)) {
1329         AssertFatal(curArg == (argc - 1), "error in bind spec somewhere...");
1330         Con::printf("Improperly specified bind for key: %s", argv[2]);
1331         return false;
1332      }
1333   }
1334
1335   // Ensure that the console function is properly specified?
1336   //
1337   // DMMTODO
1338
1339   // Create the full bind entry, and place it in the map
1340   //
1341   // DMMTODO
1342   Node* pBindNode = getNode(deviceType, deviceInst,
1343                             eventDescriptor.flags,
1344                             eventDescriptor.eventCode, object);
1345
1346   pBindNode->flags           = assignedFlags;
1347   pBindNode->deadZoneBegin   = deadZoneBegin;
1348   pBindNode->deadZoneEnd     = deadZoneEnd;
1349   pBindNode->scaleFactor     = scaleFactor;
1350   pBindNode->object          = object;
1351   pBindNode->consoleFunction = StringTable->insert(pFnName);
1352
1353   return true;
1354}
1355
1356//------------------------------------------------------------------------------
1357bool ActionMap::processHoldBind(const char *device, const char *action, const char *holdFunc, const char *tapFunc, const U32 holdTime, const bool holdOnly, const bool retHoldTime)
1358{
1359   U32 deviceType;
1360   U32 deviceInst;
1361
1362   if (!getDeviceTypeAndInstance(device, deviceType, deviceInst))
1363   {
1364      Con::printf("processBindCmd: unknown device: %s", device);
1365      return false;
1366   }
1367
1368   // Ok, we now have the deviceType and instance.  Create an event descriptor  
1369   //  for the bind...  
1370   //  
1371   EventDescriptor eventDescriptor;
1372   if (createEventDescriptor(action, &eventDescriptor) == false) {
1373      Con::printf("Could not create a description for binding: %s", action);
1374      return false;
1375   }
1376
1377   // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually.  
1378   if ((eventDescriptor.eventCode == SI_XAXIS) ||
1379      (eventDescriptor.eventCode == SI_YAXIS) ||
1380      (eventDescriptor.eventCode == SI_ZAXIS) ||
1381      (eventDescriptor.eventCode == SI_RXAXIS) ||
1382      (eventDescriptor.eventCode == SI_RYAXIS) ||
1383      (eventDescriptor.eventCode == SI_RZAXIS) ||
1384      (eventDescriptor.eventCode == SI_SLIDER) ||
1385      (eventDescriptor.eventCode == SI_XPOV) ||
1386      (eventDescriptor.eventCode == SI_YPOV) ||
1387      (eventDescriptor.eventCode == SI_XPOV2) ||
1388      (eventDescriptor.eventCode == SI_YPOV2))
1389   {
1390      Con::warnf("ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead.");
1391      return false;
1392   }
1393
1394   // Event has now been described, and device determined.  we need now to extract  
1395   //  any modifiers that the action map will apply to incoming events before  
1396   //  calling the bound function...  
1397   //  
1398   // DMMTODO  
1399   F32 deadZoneBegin = 0.0f;
1400   F32 deadZoneEnd = 0.0f;
1401   F32 scaleFactor = 1.0f;
1402
1403   // Ensure that the console function is properly specified?  
1404   //  
1405   // DMMTODO  
1406
1407   // Create the full bind entry, and place it in the map  
1408   //  
1409   // DMMTODO  
1410   Node* pBindNode = getNode(deviceType, deviceInst,
1411      eventDescriptor.flags,
1412      eventDescriptor.eventCode);
1413
1414   pBindNode->flags = Node::Held;
1415   pBindNode->deadZoneBegin = deadZoneBegin;
1416   pBindNode->deadZoneEnd = deadZoneEnd;
1417   pBindNode->scaleFactor = scaleFactor;
1418   pBindNode->consoleFunction = StringTable->insert(dStrdup(tapFunc));
1419
1420   pBindNode->contextEvent = new ContextAction(StringTable->insert(dStrdup(holdFunc)), holdTime, pBindNode, holdOnly);
1421   pBindNode->contextEvent->mReturnHoldTime = retHoldTime;
1422
1423   return true;
1424}
1425
1426//------------------------------------------------------------------------------
1427bool ActionMap::processAction(const InputEventInfo* pEvent)
1428{
1429   // Suppress excluded input events, like alt-tab.
1430   if(Platform::checkKeyboardInputExclusion(pEvent))
1431      return false;
1432
1433   static const char *argv[5];
1434   if (pEvent->action == SI_MAKE) {
1435      const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1436                                   pEvent->modifier,   pEvent->objInst);
1437
1438      if( pNode == NULL )
1439         return false;
1440
1441      // Enter the break into the table if this is a make event...
1442      // Do this now rather than after command is processed because
1443      // command might add a binding which can move the vector of nodes.
1444      // Filter to prevent Hold buttons from being eaten  
1445      if (!(pNode->flags & Node::Held))
1446         enterBreakEvent(pEvent, pNode);
1447
1448      // Whadda ya know, we have this bound.  Set up, and call the console
1449      //  function associated with it...
1450      //
1451      F32 value = pEvent->fValue;
1452      if (pNode->flags & Node::Ranged) {
1453         value = (value * 2.0f) - 1.0f;
1454         if (pNode->flags & Node::Inverted)
1455            value *= -1.0f;
1456      } else {
1457         if (pNode->flags & Node::Inverted)
1458            value = 1.0f - value;
1459      }
1460
1461      if (pNode->flags & Node::HasScale)
1462         value *= pNode->scaleFactor;
1463
1464      if ( pNode->flags & Node::HasDeadZone )
1465      {
1466         if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd ) 
1467            value = 0.0f;
1468         else
1469         {
1470            if( value > 0 )
1471               value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
1472            else
1473               value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
1474         }
1475      }
1476
1477      if( pNode->flags & Node::NonLinear )
1478         value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1479
1480      // Ok, we're all set up, call the function.
1481      if(pNode->flags & Node::BindCmd)
1482      {
1483         // it's a bind command
1484         if(pNode->makeConsoleCommand)
1485            Con::evaluate(pNode->makeConsoleCommand);
1486      }
1487      else if (pNode->flags & Node::Held)
1488      {
1489         //check if we're already holding, if not, start our timer  
1490         if (!pNode->contextEvent->mActive) {
1491            pNode->contextEvent->mActive = true;
1492            pNode->contextEvent->mStartTime = Sim::getCurrentTime();
1493            pNode->contextEvent->mEventValue = value;
1494         }
1495      }
1496      else if ( pNode->consoleFunction[0] )
1497      {
1498         argv[0] = pNode->consoleFunction;
1499         argv[1] = Con::getFloatArg(value);
1500         if (pNode->object)
1501            Con::executef(pNode->object, argv[0], argv[1]);
1502         else
1503            Con::execute(2, argv);
1504      }
1505      return true;
1506   } else if (pEvent->action == SI_MOVE) {
1507      if (pEvent->deviceType == MouseDeviceType) {
1508         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1509                                      pEvent->modifier,   pEvent->objInst);
1510
1511         if( pNode == NULL )
1512            return false;
1513
1514         // "Do nothing" bind:
1515         if ( !pNode->consoleFunction[0] )
1516            return( true );
1517
1518         // Whadda ya know, we have this bound.  Set up, and call the console
1519         //  function associated with it.  Mouse events ignore range and dead
1520         //  zone params.
1521         //
1522         F32 value = pEvent->fValue;
1523         if (pNode->flags & Node::Inverted)
1524            value *= -1.0f;
1525         if (pNode->flags & Node::HasScale)
1526            value *= pNode->scaleFactor;
1527
1528         // Ok, we're all set up, call the function.
1529         argv[0] = pNode->consoleFunction;
1530         argv[1] = Con::getFloatArg(value);
1531         if (pNode->object)
1532            Con::executef(pNode->object, argv[0], argv[1]);
1533         else
1534            Con::execute(2, argv);
1535
1536         return true;
1537      }
1538      else if ( (pEvent->objType == SI_POS || pEvent->objType == SI_FLOAT || pEvent->objType == SI_ROT || pEvent->objType == SI_INT)
1539                && INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1540              )
1541      {
1542         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1543                                      pEvent->modifier,   pEvent->objInst);
1544
1545         if( pNode == NULL )
1546            return false;
1547
1548         // Ok, we're all set up, call the function.
1549         argv[0] = pNode->consoleFunction;
1550         S32 argc = 1;
1551
1552         if (pEvent->objType == SI_INT)
1553         {
1554            // Handle the integer as some sort of motion such as a
1555            // single component to an absolute position
1556            argv[1] = Con::getIntArg( pEvent->iValue );
1557            argc += 1;
1558         }
1559         else if (pEvent->objType == SI_FLOAT)
1560         {
1561            // Handle float as some sort of motion such as a
1562            // single component to an absolute position
1563            argv[1] = Con::getFloatArg( pEvent->fValue );
1564            argc += 1;
1565         }
1566         else if (pEvent->objType == SI_POS)
1567         {
1568            // Handle Point3F type position
1569            argv[1] = Con::getFloatArg( pEvent->fValue );
1570            argv[2] = Con::getFloatArg( pEvent->fValue2 );
1571            argv[3] = Con::getFloatArg( pEvent->fValue3 );
1572
1573            argc += 3;
1574         }
1575         else
1576         {
1577            // Handle rotation (AngAxisF)
1578            AngAxisF aa(Point3F(pEvent->fValue, pEvent->fValue2, pEvent->fValue3), pEvent->fValue4);
1579            aa.axis.normalize();
1580            argv[1] = Con::getFloatArg( aa.axis.x );
1581            argv[2] = Con::getFloatArg( aa.axis.y );
1582            argv[3] = Con::getFloatArg( aa.axis.z );
1583            argv[4] = Con::getFloatArg( mRadToDeg(aa.angle) );
1584
1585            argc += 4;
1586         }
1587
1588         if (pNode->object)
1589         {
1590            Con::execute(pNode->object, argc, argv);
1591         }
1592         else
1593         {
1594            Con::execute(argc, argv);
1595         }
1596
1597         return true;
1598      }
1599      else if ( pEvent->deviceType == JoystickDeviceType 
1600                || pEvent->deviceType == GamepadDeviceType
1601                || INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1602              )
1603      {
1604         // Joystick events...
1605         const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst,
1606                                       pEvent->modifier,   pEvent->objInst );
1607
1608         if( pNode == NULL )
1609            return false;
1610
1611         // "Do nothing" bind:
1612         if ( !pNode->consoleFunction[0] )
1613            return( true );
1614
1615         // Whadda ya know, we have this bound.  Set up, and call the console
1616         //  function associated with it.  Joystick move events are the same as mouse
1617         //  move events except that they don't ignore dead zone.
1618         //
1619         F32 value = pEvent->fValue;
1620         if ( pNode->flags & Node::Inverted )
1621            value *= -1.0f;
1622
1623         if ( pNode->flags & Node::HasScale )
1624            value *= pNode->scaleFactor;
1625
1626         if ( pNode->flags & Node::HasDeadZone )
1627         {
1628            if ( value >= pNode->deadZoneBegin &&
1629                 value <= pNode->deadZoneEnd )
1630               value = 0.0f;
1631            else
1632            {
1633               if( value > 0 )
1634                  value = ( value - pNode->deadZoneEnd ) * ( 1.f / ( 1.f - pNode->deadZoneEnd ) );
1635               else
1636                  value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f + pNode->deadZoneBegin ) );
1637            }
1638         }
1639
1640         if( pNode->flags & Node::NonLinear )
1641            value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1642
1643         // Ok, we're all set up, call the function.
1644         argv[0] = pNode->consoleFunction;
1645         argv[1] = Con::getFloatArg( value );
1646         if (pNode->object)
1647            Con::executef(pNode->object, argv[0], argv[1]);
1648         else
1649            Con::execute(2, argv);
1650
1651         return true;
1652      }
1653   }
1654   else if (pEvent->action == SI_BREAK)
1655   {
1656      const Node* button = findNode(pEvent->deviceType, pEvent->deviceInst,
1657         pEvent->modifier, pEvent->objInst);
1658
1659      if (button != NULL) 
1660      {
1661         if (button->flags == Node::Held)
1662         {
1663            if (!button->contextEvent->mBreakEvent)
1664               button->contextEvent->mBreakEvent = true;
1665
1666            return true;
1667         }
1668      }
1669
1670      return checkBreakTable(pEvent);
1671   }
1672   else if (pEvent->action == SI_VALUE)
1673   {
1674      if ( (pEvent->objType == SI_FLOAT || pEvent->objType == SI_INT)
1675                && INPUTMGR->isRegisteredDevice(pEvent->deviceType)
1676              )
1677      {
1678         const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
1679                                      pEvent->modifier,   pEvent->objInst);
1680
1681         if( pNode == NULL )
1682            return false;
1683
1684         // Ok, we're all set up, call the function.
1685         argv[0] = pNode->consoleFunction;
1686         S32 argc = 1;
1687
1688         if (pEvent->objType == SI_INT)
1689         {
1690            // Handle the integer as some sort of motion such as a
1691            // single component to an absolute position
1692            argv[1] = Con::getIntArg( pEvent->iValue );
1693            argc += 1;
1694         }
1695         else if (pEvent->objType == SI_FLOAT)
1696         {
1697            // Handle float as some sort of motion such as a
1698            // single component to an absolute position
1699            argv[1] = Con::getFloatArg( pEvent->fValue );
1700            argc += 1;
1701         }
1702
1703         if (pNode->object)
1704         {
1705            Con::execute(pNode->object, argc, argv);
1706         }
1707         else
1708         {
1709            Con::execute(argc, argv);
1710         }
1711
1712         return true;
1713      }
1714   }
1715
1716   return false;
1717}
1718
1719//------------------------------------------------------------------------------
1720bool ActionMap::isAction( U32 deviceType, U32 deviceInst, U32 modifiers, U32 action )
1721{
1722   return ( findNode( deviceType, deviceInst, modifiers, action ) != NULL );
1723}
1724
1725//------------------------------------------------------------------------------
1726ActionMap* ActionMap::getGlobalMap()
1727{
1728   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1729   AssertFatal( pActionMapSet && pActionMapSet->size() != 0,
1730                "error, no ActiveMapSet or no global action map...");
1731
1732   return ( ( ActionMap* ) pActionMapSet->first() );
1733}
1734
1735//------------------------------------------------------------------------------
1736void ActionMap::enterBreakEvent(const InputEventInfo* pEvent, const Node* pNode)
1737{
1738   // There aren't likely to be many breaks outstanding at any one given time,
1739   //  so a simple linear search is probably sufficient.  Note that the break table
1740   //  is static to the class, all breaks are directed to the action map that received
1741   //  the make.
1742   //
1743   S32 entry = -1;
1744   for (U32 i = 0; i < smBreakTable.size(); i++) {
1745      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
1746          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
1747          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
1748         // Match.
1749         entry = i;
1750         break;
1751      }
1752   }
1753   if (entry == -1) {
1754      smBreakTable.increment();
1755      entry = smBreakTable.size() - 1;
1756
1757      smBreakTable[entry].deviceType = pEvent->deviceType;
1758      smBreakTable[entry].deviceInst = pEvent->deviceInst;
1759      smBreakTable[entry].objInst    = pEvent->objInst;
1760   }
1761
1762   // Ok, we now have the entry, and know that the device desc. and the objInst match.
1763   //  Copy out the node information...
1764   //
1765   smBreakTable[entry].object = pNode->object;
1766   smBreakTable[entry].consoleFunction = pNode->consoleFunction;
1767   if(pNode->breakConsoleCommand)
1768      smBreakTable[entry].breakConsoleCommand = dStrdup(pNode->breakConsoleCommand);
1769   else
1770      smBreakTable[entry].breakConsoleCommand = NULL;
1771
1772   smBreakTable[entry].flags         = pNode->flags;
1773   smBreakTable[entry].deadZoneBegin = pNode->deadZoneBegin;
1774   smBreakTable[entry].deadZoneEnd   = pNode->deadZoneEnd;
1775   smBreakTable[entry].scaleFactor   = pNode->scaleFactor;
1776}
1777
1778//------------------------------------------------------------------------------
1779bool ActionMap::checkBreakTable(const InputEventInfo* pEvent)
1780{
1781   for (U32 i = 0; i < smBreakTable.size(); i++) 
1782   {
1783      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
1784          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
1785          smBreakTable[i].objInst    == U32(pEvent->objInst)) 
1786      {
1787         fireBreakEvent(i, pEvent->fValue);
1788         return true;
1789      }
1790   }
1791
1792   return false;
1793}
1794
1795//------------------------------------------------------------------------------
1796bool ActionMap::handleEvent(const InputEventInfo* pEvent)
1797{
1798   // Interate through the ActionMapSet until we get a map that
1799   //  handles the event or we run out of maps...
1800   //
1801   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1802   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
1803               "error, no ActiveMapSet or no global action map...");
1804               
1805   for (SimSet::iterator itr = pActionMapSet->end() - 1;
1806        itr > pActionMapSet->begin(); itr--) {
1807      ActionMap* pMap = static_cast<ActionMap*>(*itr);
1808      if (pMap->processAction(pEvent) == true)
1809         return true;
1810   }
1811   
1812   // Found no matching action.  Try with the modifiers stripped.
1813
1814   InputEventInfo eventNoModifiers = *pEvent;
1815   eventNoModifiers.modifier = ( InputModifiers ) 0;
1816   
1817   for (SimSet::iterator itr = pActionMapSet->end() - 1;
1818        itr > pActionMapSet->begin(); itr--) {
1819      ActionMap* pMap = static_cast<ActionMap*>(*itr);
1820      if( pMap->processAction( &eventNoModifiers ) )
1821         return true;
1822   }
1823
1824   return false;
1825}
1826
1827//------------------------------------------------------------------------------
1828bool ActionMap::handleEventGlobal(const InputEventInfo* pEvent)
1829{
1830   return getGlobalMap()->processAction( pEvent );
1831}
1832
1833//------------------------------------------------------------------------------
1834bool ActionMap::checkAsciiGlobal( U16 key, U32 modifiers )
1835{
1836   // Does this ascii map to a key?
1837   U16 keyCode = Input::getKeyCode(key);
1838   if(keyCode == 0)
1839      return false;
1840
1841   // Grab the action map set.
1842   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
1843   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
1844      "error, no ActiveMapSet or no global action map...");
1845
1846   // Grab the device maps for the first ActionMap.
1847   Vector<DeviceMap*> &maps = ((ActionMap*)pActionMapSet->first())->mDeviceMaps;
1848
1849   // Find the keyboard.
1850   DeviceMap *keyMap = NULL;
1851   for(S32 i=0; i<maps.size(); i++)
1852   {
1853      // CodeReview Doesn't deal with multiple keyboards [bjg, 5/16/07]
1854      if(maps[i]->deviceType == KeyboardDeviceType)
1855      {
1856         keyMap = maps[i];
1857         break;
1858      }
1859   }
1860
1861   if(!keyMap)
1862      return false;
1863
1864   // Normalize modifiers.
1865   U32 realMods = modifiers;
1866   if (realMods & SI_SHIFT)
1867      realMods |= SI_SHIFT;
1868   if (realMods & SI_CTRL)
1869      realMods |= SI_CTRL;
1870   if (realMods & SI_ALT)
1871      realMods |= SI_ALT;
1872   if (realMods & SI_MAC_OPT)
1873      realMods |= SI_MAC_OPT;
1874
1875   // Now find a matching node, if there is one.
1876   for(S32 i=0; i<keyMap->nodeMap.size(); i++)
1877   {
1878      Node &n = keyMap->nodeMap[i];
1879
1880      if(n.action == keyCode && (n.modifiers == modifiers))
1881         return true;
1882   }
1883
1884   return false;
1885}
1886
1887void ActionMap::clearAllBreaks()
1888{
1889   while(smBreakTable.size())
1890      fireBreakEvent(smBreakTable.size()-1);
1891}
1892
1893void ActionMap::fireBreakEvent( U32 i, F32 fValue )
1894{
1895   // Match.  Issue the break event...
1896   //
1897   F32 value = fValue;
1898   if (smBreakTable[i].flags & Node::Ranged) {
1899      value = (value * 2.0f) - 1.0f;
1900      if (smBreakTable[i].flags & Node::Inverted)
1901         value *= -1.0f;
1902   } else {
1903      if (smBreakTable[i].flags & Node::Inverted)
1904         value = 1.0f - value;
1905   }
1906
1907   if (smBreakTable[i].flags & Node::HasScale)
1908      value *= smBreakTable[i].scaleFactor;
1909
1910   if (smBreakTable[i].flags & Node::HasDeadZone)
1911   {
1912      if (value >= smBreakTable[i].deadZoneBegin &&
1913         value <= smBreakTable[i].deadZoneEnd)
1914         value = 0.0f;
1915      else
1916      {
1917         if( value > 0 )
1918            value = ( value - smBreakTable[i].deadZoneBegin ) * ( 1.f / ( 1.f - smBreakTable[i].deadZoneBegin ) );
1919         else
1920            value = ( value + smBreakTable[i].deadZoneBegin ) * ( 1.f / ( 1.f - smBreakTable[i].deadZoneBegin ) );
1921      }
1922   }
1923
1924   if( smBreakTable[i].flags & Node::NonLinear )
1925      value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
1926
1927   // Ok, we're all set up, call the function.
1928   if(smBreakTable[i].consoleFunction)
1929   {
1930      if ( smBreakTable[i].consoleFunction[0] )
1931      {
1932         static const char *argv[2];
1933         argv[0] = smBreakTable[i].consoleFunction;
1934         argv[1] = Con::getFloatArg(value);
1935         if (smBreakTable[i].object)
1936            Con::executef(smBreakTable[i].object, argv[0], argv[1]);
1937         else
1938            Con::execute(2, argv);
1939      }
1940   }
1941   else if(smBreakTable[i].breakConsoleCommand)
1942   {
1943      Con::evaluate(smBreakTable[i].breakConsoleCommand);
1944      dFree(smBreakTable[i].breakConsoleCommand);
1945   }
1946   smBreakTable.erase(i);
1947}
1948
1949//------------------------------------------------------------------------------
1950//Context actions
1951ContextAction::ContextAction(StringTableEntry func, F32 minHoldTime, ActionMap::Node* button, bool holdOnly)
1952   : mStartTime(0), mEventValue(1.0f), mBreakEvent(false), mDidHold(false), mActive(false), mReturnHoldTime(false)
1953{
1954   mButton = button;
1955   mMinHoldTime = minHoldTime;
1956   mConsoleFunctionHeld = func;
1957
1958   mHoldOnly = holdOnly;
1959}
1960
1961void ContextAction::processTick()
1962{
1963   if (mActive)
1964   {
1965      F32 currTime = Sim::getCurrentTime();
1966      static const char *argv[2];
1967
1968      //see if this key even is still active  
1969      if (!mBreakEvent)
1970      {
1971         //are we only checking if it's holding?  
1972         if (mHoldOnly)
1973         {
1974            //yes, we are, and since it's held, we fire off our function  
1975            if (mReturnHoldTime)
1976            {
1977               argv[0] = mConsoleFunctionHeld;
1978               argv[1] = Con::getFloatArg(mEventValue);
1979               argv[2] = Con::getFloatArg((currTime - mStartTime));
1980               Con::execute(3, argv);
1981            }
1982            else
1983            {
1984               argv[0] = mConsoleFunctionHeld;
1985               argv[1] = Con::getFloatArg(mEventValue);
1986               Con::execute(2, argv);
1987            }
1988         }
1989         //if we don't care if we're just holding, check our time  
1990         //have we passed our min limit?  
1991         else if ((currTime - mStartTime) >= mMinHoldTime)
1992         {
1993            //holy crap, we have, fire off our hold function   
1994            mDidHold = true;
1995            argv[0] = mConsoleFunctionHeld;
1996            argv[1] = Con::getFloatArg(mEventValue);
1997            Con::execute(2, argv);
1998         }
1999         //otherwise we haven't yet, so keep our active status  
2000         return;
2001      }
2002      //hmm, apparently not, so see if we tapped the key instead  
2003      else
2004      {
2005         if (!mHoldOnly && !mDidHold)
2006         {
2007            //yes, we tapped and we care, so fire off the tap function.  
2008            argv[0] = mButton->consoleFunction;
2009            argv[1] = Con::getFloatArg(mEventValue);
2010            Con::execute(2, argv);
2011         }
2012         //otherwise we don't care and we're done, so reset everything  
2013         mActive = false;
2014         mStartTime = 0;
2015         mBreakEvent = false;
2016         mDidHold = false;
2017      }
2018   }
2019}
2020
2021//------------------------------------------------------------------------------
2022
2023// Console interop version.
2024
2025static ConsoleDocFragment _ActionMapbind1(
2026   "@brief Associates a function to an input event.\n\n"
2027   "When the input event is raised, the specified function will be called.\n\n"
2028   "@param device The input device, such as mouse or keyboard.\n"
2029   "@param action The input event, such as space, button0, etc.\n"
2030   "@param command The function to bind to the action. Function must have a single boolean argument.\n"
2031   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
2032   "@tsexample\n"
2033   "// Simple function that prints to console\n"
2034   "// %val - Sent by the device letting the user know\n"
2035   "// if an input was pressed (true) or released (false)\n"
2036   "function testInput(%val)\n"
2037   "{\n"
2038   "   if(%val)\n"
2039   "    echo(\"Key is down\");\n"
2040   "   else\n"
2041   "    echo(\"Key was released\");\n"
2042   "}\n\n"
2043   "// Bind the \'K\' key to the testInput function\n"
2044   "moveMap.bind(keyboard, k, testInput);\n\n"
2045   "@endtsexample\n\n\n",
2046   "ActionMap",
2047   "bool bind( string device, string action, string command );");
2048
2049static ConsoleDocFragment _ActionMapbind2(
2050   "@brief Associates a function and input parameters to an input event.\n\n"
2051   "When the input event is raised, the specified function will be called. Modifier flags may be specified to process "
2052   "dead zones, input inversion, and more.\n\n"
2053   "Valid modifier flags:\n\n"
2054   " - R - Input is Ranged.\n"
2055   " - S - Input is Scaled.\n"
2056   " - I - Input is inverted.\n"
2057   " - D - Dead zone is present.\n"
2058   " - N - Input should be re-fit to a non-linear scale.\n\n"
2059   "@param device The input device, such as mouse or keyboard.\n"
2060   "@param action The input event, such as space, button0, etc.\n"
2061   "@param flag Modifier flag assigned during binding, letting event know there are additional parameters to consider. \n"
2062   "@param deadZone Restricted region in which device motion will not be acknowledged.\n"
2063   "@param scale Modifies the deadZone region.\n"
2064   "@param command The function bound to the action. Must take in a single argument.\n"
2065   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
2066   "@tsexample\n"
2067   "// Simple function that adjusts the pitch of the camera based on the "
2068   "mouse's movement along the X axis.\n"
2069   "function testPitch(%val)\n"
2070   "{\n"
2071   "   %pitchAdj = getMouseAdjustAmount(%val);\n"
2072   "   $mvPitch += %pitchAdj;\n"
2073   "}\n\n"
2074   "// Bind the mouse's X axis to the testPitch function\n"
2075   "// DI is flagged, meaning input is inverted and has a deadzone\n"
2076   "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n"
2077   "@endtsexample\n\n\n",
2078   "ActionMap",
2079   "bool bind( string device, string action, string flag, string deadZone, string scale, string command );");
2080
2081DefineEngineStringlyVariadicMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier, spec, mod...], command )"
2082           "@hide")
2083{
2084   StringStackWrapper args(argc - 2, argv + 2);
2085   return object->processBind( args.count(), args, NULL );
2086}
2087
2088static ConsoleDocFragment _ActionMapbindObj1(
2089   "@brief Associates a function to an input event for a specified class or object.\n\n"
2090   "You must specify a device, the action to bind, a function, and an object to be called when the event happens. "
2091   "The function specified must be set to receive a single boolean value passed.\n\n"
2092   "@param device The input device, such as mouse or keyboard.\n"
2093   "@param action The input event, such as space, button0, etc.\n"
2094   "@param command The function bound to the action.\n"
2095   "@param object The object or class bound to the action.\n"
2096   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
2097   "@tsexample\n"
2098   "moveMap.bindObj(keyboard, \"numpad1\", \"rangeChange\", %player);"
2099   "@endtsexample\n\n",
2100   "ActionMap",
2101   "bool bindObj( string device, string action, string command, SimObjectID object );");
2102
2103static ConsoleDocFragment _ActionMapbindObj2(
2104   "@brief Associates a function to an input event for a specified class or object.\n\n"
2105   "You must specify a device, the action to bind, a function, and an object to be called when the event happens. "
2106   "The function specified must be set to receive a single boolean value passed. Modifier flags may be specified to process "
2107   "dead zones, input inversion, and more.\n\n"
2108   "Valid modifier flags:\n\n"
2109   " - R - Input is Ranged.\n"
2110   " - S - Input is Scaled.\n"
2111   " - I - Input is inverted.\n"
2112   " - D - Dead zone is present.\n"
2113   " - N - Input should be re-fit to a non-linear scale.\n\n"
2114   "@param device The input device, such as mouse or keyboard.\n"
2115   "@param action The input event, such as space, button0, etc.\n"
2116   "@param flag Modifier flag assigned during binding, letting event know there are additional parameters to consider.\n"
2117   "@param deadZone [Required only when flag is set] Restricted region in which device motion will not be acknowledged.\n"
2118   "@param scale [Required only when flag is set] Modifies the deadZone region.\n"
2119   "@param command The function bound to the action.\n"
2120   "@param object The object or class bound to the action.\n"
2121   "@return True if the binding was successful, false if the device was unknown or description failed.\n\n"
2122   "@tsexample\n"
2123   "// Bind the mouse's movement along the x-axis to the testInput function of the Player class\n"
2124   "// DSI is flagged, meaning input is inverted, has scale and has a deadzone\n"
2125   "%this.bindObj( mouse, \"xaxis\", \"DSI\", %deadZone, %scale, \"testInput\", %player );\n"
2126   "@endtsexample\n\n\n",
2127   "ActionMap",
2128   "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );");
2129
2130DefineEngineStringlyVariadicMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier, spec, mod...], command, object)"
2131           "@hide")
2132{
2133   SimObject* simObject = Sim::findObject(argv[argc - 1]);
2134   if ( simObject == NULL )
2135   {
2136      Con::warnf("ActionMap::bindObj() - Cannot bind, specified object was not found!");
2137      return false;
2138   }
2139
2140   StringStackWrapper args(argc - 3, argv + 2);
2141   return object->processBind( args.count(), args, simObject );
2142}
2143
2144//------------------------------------------------------------------------------
2145
2146DefineEngineMethod( ActionMap, bindCmd, bool, ( const char* device, const char* action, const char* makeCmd, const char* breakCmd ), ( "" ),
2147    "@brief Associates a make command and optional break command to a specified input device action.\n\n"
2148    "Must include parenthesis and semicolon in the make and break command strings.\n\n"
2149    "@param device The device to bind to. Can be a keyboard, mouse, joystick or gamepad.\n"
2150    "@param action The device action to bind to. The action is dependant upon the device. Specify a key for keyboards.\n"
2151    "@param makeCmd The command to execute when the device/action is made.\n"
2152    "@param breakCmd [optional] The command to execute when the device or action is unmade.\n"
2153    "@return True the bind was successful, false if the device was unknown or description failed.\n"
2154   "@tsexample\n"
2155   "// Print to the console when the spacebar is pressed\n"
2156   "function onSpaceDown()\n"
2157   "{\n"
2158   "   echo(\"Space bar down!\");\n"
2159   "}\n\n"
2160   "// Print to the console when the spacebar is released\n"
2161   "function onSpaceUp()\n"
2162   "{\n"
2163   "   echo(\"Space bar up!\");\n"
2164   "}\n\n"
2165   "// Bind the commands onSpaceDown() and onSpaceUp() to spacebar events\n\n"
2166   "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n"
2167   "@endtsexample\n\n")
2168{
2169   return object->processBindCmd( device, action, makeCmd, breakCmd );
2170}
2171
2172DefineEngineMethod(ActionMap, bindContext, void, (const char* device, const char* action, const char* holdFunction, const char* tapFunction, U32 holdTime),
2173   ("", "", "", "", 0), "actionMap.bindCmd( device, action, holdFunction, tapFunction, holdTime)")
2174{
2175   object->processHoldBind(device, action, holdFunction, tapFunction, holdTime, false);
2176}
2177
2178DefineEngineMethod(ActionMap, bindHold, void, (const char* device, const char* action, const char* holdFunction, bool returnHoldTime),
2179   ("", "", "", false), "actionMap.bindCmd( device, action, holdFunction, returnHoldTime)")
2180{
2181   object->processHoldBind(device, action, holdFunction, "", 0, true, returnHoldTime);
2182}
2183
2184DefineEngineMethod( ActionMap, unbind, bool, ( const char* device, const char* action ),,
2185   "@brief Removes the binding on an input device and action.\n"
2186   "@param device The device to unbind from. Can be a keyboard, mouse, joystick or a gamepad.\n"
2187   "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n"
2188   "@return True if the unbind was successful, false if the device was unknown or description failed.\n\n"
2189   "@tsexample\n"
2190   "moveMap.unbind(\"keyboard\", \"space\");\n"
2191   "@endtsexample\n\n")
2192{
2193   return object->processUnbind( device, action );
2194}
2195
2196DefineEngineMethod( ActionMap, unbindObj, bool, ( const char* device, const char* action, const char* obj ),,
2197   "@brief Remove any object-binding on an input device and action.\n"
2198   "@param device The device to bind to.  Can be keyboard, mouse, joystick or gamepad.\n"
2199   "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n"
2200   "@param obj The object to perform unbind against.\n"
2201   "@return True if the unbind was successful, false if the device was unknown or description failed.\n"
2202   "@tsexample\n"
2203   "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);"
2204   "@endtsexample\n\n\n")
2205{
2206    SimObject* simObject = Sim::findObject(obj);
2207    if ( simObject == NULL )
2208    {
2209        Con::warnf("ActionMap::unbindObj() - Cannot unbind, specified object was not found!");
2210        return false;
2211    }
2212
2213    return object->processUnbind( device, action, simObject );
2214}
2215
2216DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ), ( nullAsType<const char*>(), false ),
2217   "@brief Saves the ActionMap to a file or dumps it to the console.\n\n"
2218   "@param fileName The file path to save the ActionMap to. If a filename is not specified "
2219   " the ActionMap will be dumped to the console.\n"
2220   "@param append Whether to write the ActionMap at the end of the file or overwrite it.\n"
2221   "@tsexample\n"
2222   "// Write out the actionmap into the config." TORQUE_SCRIPT_EXTENSION " file\n"
2223   "moveMap.save( \"scripts/client/config." TORQUE_SCRIPT_EXTENSION "\" );"
2224   "@endtsexample\n\n")
2225{
2226   char buffer[1024];
2227
2228   if(fileName)
2229   {
2230      if(Con::expandScriptFilename(buffer, sizeof(buffer), fileName))
2231         fileName = buffer;
2232   }
2233
2234   object->dumpActionMap( fileName, append );
2235}
2236
2237DefineEngineFunction( getCurrentActionMap, ActionMap*, (),,
2238   "@brief Returns the current %ActionMap.\n"
2239   "@see ActionMap"
2240   "@ingroup Input")
2241{
2242   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2243   return dynamic_cast< ActionMap* >( pActionMapSet->last() );
2244}
2245
2246DefineEngineMethod( ActionMap, push, void, (),,
2247   "@brief Push the ActionMap onto the %ActionMap stack.\n\n"
2248   "Activates an ActionMap and placees it at the top of the ActionMap stack.\n\n"
2249   "@tsexample\n"
2250   "// Make moveMap the active action map\n"
2251   "moveMap.push();\n"
2252   "@endtsexample\n\n"
2253   "@see ActionMap")
2254{
2255   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2256   pActionMapSet->pushObject( object );
2257}
2258
2259DefineEngineMethod( ActionMap, pop, void, (),,
2260   "@brief Pop the ActionMap off the %ActionMap stack.\n\n"
2261   "Deactivates an %ActionMap and removes it from the @ActionMap stack.\n"
2262   "@tsexample\n"
2263   "// Deactivate moveMap\n"
2264   "moveMap.pop();\n"
2265   "@endtsexample\n\n"
2266   "@see ActionMap")
2267{
2268   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
2269   pActionMapSet->removeObject( object );
2270}
2271
2272DefineEngineMethod( ActionMap, getBinding, const char*, ( const char* command ),,
2273   "@brief Gets the ActionMap binding for the specified command.\n\n"
2274   "Use getField() on the return value to get the device and action of the binding.\n"
2275   "@param command The function to search bindings for.\n"
2276   "@return The binding against the specified command. Returns an empty string(\"\") "
2277   "if a binding wasn't found.\n"
2278   "@tsexample\n"
2279   "// Find what the function \"jump()\" is bound to in moveMap\n"
2280   "%bind = moveMap.getBinding( \"jump\" );\n\n"
2281   "if ( %bind !$= \"\" )\n"
2282   "{\n"
2283   "// Find out what device is used in the binding\n"
2284   "  %device = getField( %bind, 0 );\n\n"
2285   "// Find out what action (such as a key) is used in the binding\n"
2286   "  %action = getField( %bind, 1 );\n"
2287   "}\n"
2288   "@endtsexample\n\n"
2289   "@see getField")
2290{
2291   return object->getBinding( command );  
2292}
2293
2294DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, const char* action ),,
2295   "@brief Gets ActionMap command for the device and action.\n\n"
2296   "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n"
2297   "@param action The device action that was bound.  The action is dependant upon the device. Specify a key for keyboards.\n"
2298   "@return The command against the specified device and action.\n"
2299   "@tsexample\n"
2300   "// Find what function is bound to a device\'s action\n"
2301   "// In this example, \"jump()\" was assigned to the space key in another script\n"
2302   "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n"
2303   "// Should print \"jump\" in the console\n"
2304   "echo(%command)\n"
2305   "@endtsexample\n\n")
2306{
2307   return object->getCommand( device, action ); 
2308}
2309
2310DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const char* action ),,
2311   "@brief Determines if the specified device and action is inverted.\n\n"
2312   "Should only be used for scrolling devices or gamepad/joystick axes."
2313   "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n"
2314   "@param action The device action that was bound.  The action is dependant upon the device. Specify a key for keyboards.\n"
2315   "@return True if the specified device and action is inverted.\n"
2316   "@tsexample\n"
2317   "%if ( moveMap.isInverted( \"mouse\", \"xaxis\"))\n"
2318   "   echo(\"Mouse's xAxis is inverted\");"
2319   "@endtsexample\n\n")
2320{
2321   return object->isInverted( device, action ); 
2322}
2323
2324DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* action ),,
2325   "@brief Get any scaling on the specified device and action.\n\n"
2326   "@param device The device that was bound. Can be keyboard, mouse, joystick or gamepad.\n"
2327   "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n"
2328   "@return Any scaling applied to the specified device and action.\n"
2329   "@tsexample\n"
2330   "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n"
2331   "@endtsexample\n\n")
2332{
2333   return object->getScale( device, action );   
2334}
2335
2336DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, const char* action ),,
2337   "@brief Gets the Dead zone for the specified device and action.\n\n"
2338   "@param device The device that was bound.  Can be a keyboard, mouse, joystick or a gamepad.\n"
2339   "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n"
2340   "@return The dead zone for the specified device and action. Returns \"0 0\" if there is no dead zone " 
2341   "or an empty string(\"\") if the mapping was not found.\n"
2342   "@tsexample\n"
2343   "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n"
2344   "@endtsexample\n\n")
2345{
2346   return object->getDeadZone( device, action );   
2347}
2348
2349//------------------------------------------------------------------------------
2350AsciiMapping gAsciiMap[] =
2351{
2352   //--- KEYBOARD EVENTS
2353   //
2354   { "space",           0x0020 },
2355   //{ "exclamation",     0x0021 },
2356   { "doublequote",     0x0022 },
2357   //{ "pound",           0x0023 },
2358   //{ "ampersand",       0x0026 },
2359   { "apostrophe",      0x0027 },
2360   //{ "lparen",          0x0028 },
2361   //{ "rparen",          0x0029 },
2362   { "comma",           0x002c },
2363   { "minus",           0x002d },
2364   { "period",          0x002e },
2365   //{ "slash",           0x002f },
2366   //{ "colon",           0x003a },
2367   //{ "semicolon",       0x003b },
2368   //{ "lessthan",        0x003c },
2369   //{ "equals",          0x003d },
2370   //{ "morethan",        0x003e },
2371   //{ "lbracket",        0x005b },
2372   { "backslash",       0x005c },
2373   //{ "rbracket",        0x005d },
2374   //{ "circumflex",      0x005e },
2375   //{ "underscore",      0x005f },
2376   { "grave",           0x0060 },
2377   //{ "tilde",           0x007e },
2378   //{ "vertbar",         0x007c },
2379   //{ "exclamdown",      0x00a1 },
2380   //{ "cent",            0x00a2 },
2381   //{ "sterling",        0x00a3 },
2382   //{ "currency",        0x00a4 },
2383   //{ "brokenbar",       0x00a6 },
2384   //{ "ring",            0x00b0 },
2385   //{ "plusminus",       0x00b1 },
2386   { "super2",          0x00b2 },
2387   { "super3",          0x00b3 },
2388   { "acute",           0x00b4 },
2389   //{ "mu",              0x00b5 },
2390   //{ "ordmasculine",    0x00ba },
2391   //{ "questiondown",    0x00bf },
2392   //{ "gemandbls",       0x00df },
2393   //{ "agrave",          0x00e0 },
2394   //{ "aacute",          0x00e1 },
2395   //{ "acircumflex",     0x00e2 },
2396   //{ "atilde",          0x00e3 },
2397   //{ "adieresis",       0x00e4 },
2398   //{ "aring",           0x00e5 },
2399   //{ "ae",              0x00e6 },
2400   //{ "ccedille",        0x00e7 },
2401   //{ "egrave",          0x00e8 },
2402   //{ "eacute",          0x00e9 },
2403   //{ "ecircumflex",     0x00ea },
2404   //{ "edieresis",       0x00eb },
2405   //{ "igrave",          0x00ec },
2406   //{ "iacute",          0x00ed },
2407   //{ "icircumflex",     0x00ee },
2408   //{ "idieresis",       0x00ef },
2409   //{ "ntilde",          0x00f1 },
2410   //{ "ograve",          0x00f2 },
2411   //{ "oacute",          0x00f3 },
2412   //{ "ocircumflex",     0x00f4 },
2413   //{ "otilde",          0x00f5 },
2414   //{ "odieresis",       0x00f6 },
2415   //{ "divide",          0x00f7 },
2416   //{ "oslash",          0x00f8 },
2417   //{ "ugrave",          0x00f9 },
2418   //{ "uacute",          0x00fa },
2419   //{ "ucircumflex",     0x00fb },
2420   //{ "udieresis",       0x00fc },
2421   //{ "ygrave",          0x00fd },
2422   //{ "thorn",           0x00fe },
2423   //{ "ydieresis",       0x00ff },
2424   { "nomatch",         0xFFFF }
2425};
2426