winDirectInput.cpp
Engine/source/platformWin32/winDirectInput.cpp
Public Defines
define
CHECK_PROP_ANALOG(prop, stateTest) case prop: (current) ? retVal = mXInputStateNew[controllerID].state.Gamepad.stateTest : retVal = mXInputStateOld[controllerID].state.Gamepad.stateTest; return retVal;
define
CHECK_PROP_DIGITAL(prop, stateTest) case prop: (current) ? retVal = (( mXInputStateNew[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ) : retVal = (( mXInputStateOld[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ); return retVal;
define
GET_XI_STATE(constName) (!(properties, #constName)) \ return mgr->getXInputState( controllerID, constName, ( current ));
Public Typedefs
HRESULT(WINAPI *
FN_DirectInputCreate )(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter)
Public Functions
DefineEngineFunction(disableJoystick , void , () , "()" "@brief Disables use of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">joystick.\n\n</a>" "@note DirectInput must be enabled and active <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(disableXInput , void , () , "()" "@brief Disables XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controllers.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(echoInputState , void , () , "()" "@brief Prints information <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console stating <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> DirectInput and <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Joystick are enabled and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">active.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(enableJoystick , bool , () , "()" "@brief Enables use of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">joystick.\n\n</a>" "@note DirectInput must be enabled and active <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(enableXInput , bool , () , "()" "@brief Enables XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controllers.\n\n</a>" "@note XInput is enabled by default. Disable <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use an Xbox 360 " "Controller as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(getXInputState , int , (S32 controllerID, const char *properties, bool current) , (false) , "( int controllerID, string property, bool currentD )" "@brief Queries the current state of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> connected Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controller.\n\n</a>" "XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Properties:\n\n</a>" " - XI_THUMBLX, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba945e7b6df6de0357f082190c556b5e1a">XI_THUMBLY</a> - X and Y axes of the left thumbstick. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - XI_THUMBRX, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebad57dc3b2ca1ea2059595bcb5860a31ed">XI_THUMBRY</a> - X and Y axes of the right thumbstick. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - XI_LEFT_TRIGGER, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba846aa818779c87f20868835c68893e26">XI_RIGHT_TRIGGER</a> - Left and Right triggers. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - SI_UPOV, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba2d1c3fea4b69532e2d48fb8cb0bf96cf">SI_DPOV</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaf23a7bc5ade65e9b299d5f161254dddf">SI_LPOV</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba59a21904b7130ab59b91f94e1a836d1b">SI_RPOV</a> - Up, Down , Left , and Right on the directional <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pad.\n</a>" " - XI_START, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba72e989d282cd4b6535f81e2d97a6b0d7">XI_BACK</a> - The Start and Back <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buttons.\n</a>" " - XI_LEFT_THUMB, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba173eb79e0cf67e7f409292f9c7a2d186">XI_RIGHT_THUMB</a> - Clicking in the left and right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">thumbstick.\n</a>" " - XI_LEFT_SHOULDER, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaae8a2ae1034fbf1fc728b46f6e4b8979">XI_RIGHT_SHOULDER</a> - Left and Right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">bumpers.\n</a>" " - XI_A, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba4916b6252b32583ed60830e7e000db92">XI_B</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba052c2346d752811afa615db5e095eca9">XI_X</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaff4b898d66753c4838a5915a1507cdf1">XI_Y</a> - The A, B , X , and Y <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buttons.\n\n</a>" " @param controllerID Zero-based index of the controller <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> return information <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">about.\n</a>" " @param property Name of input action being queried, such as \"XI_THUMBLX\".\n" "@param current True checks current device in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@return Button queried - 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the button is pressed, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" " @return Thumbstick queried - Int representing displacement from rest position." " @return %<a href="/coding/class/classtrigger/">Trigger</a> queried - Int from 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> 255 representing how far the trigger is displaced." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(isJoystickEnabled , bool , () , "()" "@brief Queries input manager <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enabled\n\n</a>" "@return 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick exists and is enabled, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(isXInputConnected , bool , (S32 controllerID) , "( int controllerID )" "@brief Checks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an Xbox 360 controller is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">connected\n\n</a>" "@param controllerID Zero-based index of the controller <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">check.\n</a>" "@return 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the controller is connected, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it isn ' t, and 205 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> XInput " "hasn '<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> been initialized." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(resetXInput , void , () , "()" "@brief Rebuilds the XInput section of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">InputManager\n\n</a>" "Requests <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> full refresh of events <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> all controllers. Useful when called at the beginning " "of game code after actionMaps are set up <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> hook up all appropriate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(rumble , void , (const char *device, F32 xRumble, F32 yRumble) , "(string device, float xRumble, float yRumble)" "@brief Activates the vibration motors in the specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controller.\n\n</a>" "The controller will constantly at it's xRumble and yRumble intensities until " "changed or told <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stop." "Valid inputs <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> xRumble/yRumble are .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param device Name of the device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rumble.\n</a>" "@param xRumble Intensity <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the left <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">motor.\n</a>" "@param yRumble Intensity <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">motor.\n</a>" "@note in an Xbox 360 controller, the left motor is low- frequency, " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the right motor is high-frequency." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
Detailed Description
Public Defines
CHECK_PROP_ANALOG(prop, stateTest) case prop: (current) ? retVal = mXInputStateNew[controllerID].state.Gamepad.stateTest : retVal = mXInputStateOld[controllerID].state.Gamepad.stateTest; return retVal;
CHECK_PROP_DIGITAL(prop, stateTest) case prop: (current) ? retVal = (( mXInputStateNew[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ) : retVal = (( mXInputStateOld[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ); return retVal;
GET_XI_STATE(constName) (!(properties, #constName)) \ return mgr->getXInputState( controllerID, constName, ( current ));
Public Typedefs
typedef HRESULT(WINAPI * FN_DirectInputCreate )(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter)
Public Functions
DefineEngineFunction(disableJoystick , void , () , "()" "@brief Disables use of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">joystick.\n\n</a>" "@note DirectInput must be enabled and active <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(disableXInput , void , () , "()" "@brief Disables XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controllers.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(echoInputState , void , () , "()" "@brief Prints information <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console stating <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> DirectInput and <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Joystick are enabled and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">active.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(enableJoystick , bool , () , "()" "@brief Enables use of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">joystick.\n\n</a>" "@note DirectInput must be enabled and active <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(enableXInput , bool , () , "()" "@brief Enables XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controllers.\n\n</a>" "@note XInput is enabled by default. Disable <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use an Xbox 360 " "Controller as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(getXInputState , int , (S32 controllerID, const char *properties, bool current) , (false) , "( int controllerID, string property, bool currentD )" "@brief Queries the current state of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> connected Xbox 360 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controller.\n\n</a>" "XInput <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Properties:\n\n</a>" " - XI_THUMBLX, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba945e7b6df6de0357f082190c556b5e1a">XI_THUMBLY</a> - X and Y axes of the left thumbstick. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - XI_THUMBRX, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebad57dc3b2ca1ea2059595bcb5860a31ed">XI_THUMBRY</a> - X and Y axes of the right thumbstick. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - XI_LEFT_TRIGGER, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba846aa818779c87f20868835c68893e26">XI_RIGHT_TRIGGER</a> - Left and Right triggers. \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " - SI_UPOV, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba2d1c3fea4b69532e2d48fb8cb0bf96cf">SI_DPOV</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaf23a7bc5ade65e9b299d5f161254dddf">SI_LPOV</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba59a21904b7130ab59b91f94e1a836d1b">SI_RPOV</a> - Up, Down , Left , and Right on the directional <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pad.\n</a>" " - XI_START, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba72e989d282cd4b6535f81e2d97a6b0d7">XI_BACK</a> - The Start and Back <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buttons.\n</a>" " - XI_LEFT_THUMB, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba173eb79e0cf67e7f409292f9c7a2d186">XI_RIGHT_THUMB</a> - Clicking in the left and right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">thumbstick.\n</a>" " - XI_LEFT_SHOULDER, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaae8a2ae1034fbf1fc728b46f6e4b8979">XI_RIGHT_SHOULDER</a> - Left and Right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">bumpers.\n</a>" " - XI_A, <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba4916b6252b32583ed60830e7e000db92">XI_B</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2eba052c2346d752811afa615db5e095eca9">XI_X</a> , <a href="/coding/group/group__input__constants/#group__input__constants_1ggabe97be4d441d7e2653e24933583bb2ebaff4b898d66753c4838a5915a1507cdf1">XI_Y</a> - The A, B , X , and Y <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buttons.\n\n</a>" " @param controllerID Zero-based index of the controller <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> return information <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">about.\n</a>" " @param property Name of input action being queried, such as \"XI_THUMBLX\".\n" "@param current True checks current device in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">action.\n</a>" "@return Button queried - 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the button is pressed, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" " @return Thumbstick queried - Int representing displacement from rest position." " @return %<a href="/coding/class/classtrigger/">Trigger</a> queried - Int from 0 <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> 255 representing how far the trigger is displaced." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(isJoystickEnabled , bool , () , "()" "@brief Queries input manager <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enabled\n\n</a>" "@return 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> joystick exists and is enabled, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it 's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">not.\n</a>" " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(isXInputConnected , bool , (S32 controllerID) , "( int controllerID )" "@brief Checks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an Xbox 360 controller is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">connected\n\n</a>" "@param controllerID Zero-based index of the controller <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">check.\n</a>" "@return 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the controller is connected, 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it isn ' t, and 205 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> XInput " "hasn '<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> been initialized." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(resetXInput , void , () , "()" "@brief Rebuilds the XInput section of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">InputManager\n\n</a>" "Requests <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> full refresh of events <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> all controllers. Useful when called at the beginning " "of game code after actionMaps are set up <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> hook up all appropriate <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">events.\n\n</a>" "@ingroup <a href="/coding/class/classinput/">Input</a>" )
DefineEngineFunction(rumble , void , (const char *device, F32 xRumble, F32 yRumble) , "(string device, float xRumble, float yRumble)" "@brief Activates the vibration motors in the specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">controller.\n\n</a>" "The controller will constantly at it's xRumble and yRumble intensities until " "changed or told <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> stop." "Valid inputs <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> xRumble/yRumble are .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param device Name of the device <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rumble.\n</a>" "@param xRumble Intensity <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the left <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">motor.\n</a>" "@param yRumble Intensity <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">motor.\n</a>" "@note in an Xbox 360 controller, the left motor is low- frequency, " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a0e48c1f64b558d03d870367324920354">while</a> the right motor is high-frequency." " @ingroup <a href="/coding/class/classinput/">Input</a>" )
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 "platformWin32/platformWin32.h" 25#include "platformWin32/winDirectInput.h" 26#include "platformWin32/winDInputDevice.h" 27#include "console/console.h" 28#include "console/consoleTypes.h" 29#include "console/engineAPI.h" 30#include "sim/actionMap.h" 31 32#include <xinput.h> 33 34//------------------------------------------------------------------------------ 35// Static class variables: 36bool DInputManager::smJoystickEnabled = true; 37bool DInputManager::smXInputEnabled = true; 38 39// Type definitions: 40typedef HRESULT (WINAPI* FN_DirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); 41 42//------------------------------------------------------------------------------ 43DInputManager::DInputManager() 44{ 45 mEnabled = false; 46 mDInputLib = NULL; 47 mDInputInterface = NULL; 48 mJoystickActive = mXInputActive = true; 49 mXInputLib = NULL; 50 51 mfnXInputGetState = NULL; 52 mfnXInputSetState = NULL; 53 dMemset(mXInputStateOld, 0, sizeof(mXInputStateOld)); 54 dMemset(mXInputStateNew, 0, sizeof(mXInputStateNew)); 55 mXInputStateReset = false; 56 mXInputDeadZoneOn = true; 57 58 for(S32 i=0; i<4; i++) 59 mLastDisconnectTime[i] = -1; 60} 61 62//------------------------------------------------------------------------------ 63void DInputManager::init() 64{ 65 Con::addVariable( "pref::Input::JoystickEnabled", TypeBool, &smJoystickEnabled, 66 "@brief If true, the joystick is currently enabled.\n\n" 67 "@ingroup Game"); 68} 69 70//------------------------------------------------------------------------------ 71bool DInputManager::enable() 72{ 73 FN_DirectInputCreate fnDInputCreate; 74 75 disable(); 76 77 // Dynamically load the XInput 9 DLL and cache function pointers to the 78 // two APIs we use 79#ifdef LOG_INPUT 80 Input::log( "Enabling XInput...\n" ); 81#endif 82 mXInputLib = LoadLibrary( dT("xinput9_1_0.dll") ); 83 if ( mXInputLib ) 84 { 85 mfnXInputGetState = (FN_XInputGetState) GetProcAddress( mXInputLib, "XInputGetState" ); 86 mfnXInputSetState = (FN_XInputSetState) GetProcAddress( mXInputLib, "XInputSetState" ); 87 if ( mfnXInputGetState && mfnXInputSetState ) 88 { 89#ifdef LOG_INPUT 90 Input::log( "XInput detected.\n" ); 91#endif 92 mXInputStateReset = true; 93 mXInputDeadZoneOn = true; 94 smXInputEnabled = true; 95 } 96 } 97 else 98 { 99#ifdef LOG_INPUT 100 Input::log( "XInput was not found.\n" ); 101 mXInputStateReset = false; 102 mXInputDeadZoneOn = false; 103#endif 104 } 105 106#ifdef LOG_INPUT 107 Input::log( "Enabling DirectInput...\n" ); 108#endif 109 mDInputLib = LoadLibrary( dT("DInput8.dll") ); 110 if ( mDInputLib ) 111 { 112 fnDInputCreate = (FN_DirectInputCreate) GetProcAddress( mDInputLib, "DirectInput8Create" ); 113 if ( fnDInputCreate ) 114 { 115 bool result = SUCCEEDED( fnDInputCreate( winState.appInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void**>(&mDInputInterface), NULL )); 116 if ( result ) 117 { 118#ifdef LOG_INPUT 119 Input::log( "DirectX 8 or greater detected.\n" ); 120#endif 121 } 122 123 if ( result ) 124 { 125 enumerateDevices(); 126 mEnabled = true; 127 return true; 128 } 129 } 130 } 131 132 disable(); 133 134#ifdef LOG_INPUT 135 Input::log( "Failed to enable DirectInput.\n" ); 136#endif 137 138 return false; 139} 140 141//------------------------------------------------------------------------------ 142 143void DInputManager::disable() 144{ 145 unacquire( SI_ANY, SI_ANY ); 146 147 DInputDevice* dptr; 148 iterator ptr = begin(); 149 while ( ptr != end() ) 150 { 151 dptr = dynamic_cast<DInputDevice*>( *ptr ); 152 if ( dptr ) 153 { 154 removeObject( dptr ); 155 //if ( dptr->getManager() ) 156 //dptr->getManager()->unregisterObject( dptr ); 157 delete dptr; 158 ptr = begin(); 159 } 160 else 161 ptr++; 162 } 163 164 if ( mDInputInterface ) 165 { 166 mDInputInterface->Release(); 167 mDInputInterface = NULL; 168 } 169 170 if ( mDInputLib ) 171 { 172 FreeLibrary( mDInputLib ); 173 mDInputLib = NULL; 174 } 175 176 if ( mfnXInputGetState ) 177 { 178 mXInputStateReset = true; 179 mfnXInputGetState = NULL; 180 mfnXInputSetState = NULL; 181 } 182 183 if ( mXInputLib ) 184 { 185 FreeLibrary( mXInputLib ); 186 mXInputLib = NULL; 187 } 188 189 mEnabled = false; 190} 191 192//------------------------------------------------------------------------------ 193void DInputManager::onDeleteNotify( SimObject* object ) 194{ 195 Parent::onDeleteNotify( object ); 196} 197 198//------------------------------------------------------------------------------ 199bool DInputManager::onAdd() 200{ 201 if ( !Parent::onAdd() ) 202 return false; 203 204 acquire( SI_ANY, SI_ANY ); 205 return true; 206} 207 208//------------------------------------------------------------------------------ 209void DInputManager::onRemove() 210{ 211 unacquire( SI_ANY, SI_ANY ); 212 Parent::onRemove(); 213} 214 215//------------------------------------------------------------------------------ 216bool DInputManager::acquire( U8 deviceType, U8 deviceID ) 217{ 218 bool anyActive = false; 219 DInputDevice* dptr; 220 for ( iterator ptr = begin(); ptr != end(); ptr++ ) 221 { 222 dptr = dynamic_cast<DInputDevice*>( *ptr ); 223 if ( dptr 224 && ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) ) 225 && ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) ) 226 { 227 if ( dptr->acquire() ) 228 anyActive = true; 229 } 230 } 231 232 return anyActive; 233} 234 235//------------------------------------------------------------------------------ 236void DInputManager::unacquire( U8 deviceType, U8 deviceID ) 237{ 238 DInputDevice* dptr; 239 for ( iterator ptr = begin(); ptr != end(); ptr++ ) 240 { 241 dptr = dynamic_cast<DInputDevice*>( *ptr ); 242 if ( dptr 243 && ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) ) 244 && ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) ) 245 dptr->unacquire(); 246 } 247} 248 249//------------------------------------------------------------------------------ 250void DInputManager::process() 251{ 252 // Because the XInput APIs manage everything for all four controllers trivially, 253 // we don't need the abstraction of a DInputDevice for an unknown number of devices 254 // with varying buttons & whistles... nice and easy! 255 if ( isXInputActive() ) 256 processXInput(); 257 258 DInputDevice* dptr; 259 for ( iterator ptr = begin(); ptr != end(); ptr++ ) 260 { 261 dptr = dynamic_cast<DInputDevice*>( *ptr ); 262 if ( dptr ) 263 dptr->process(); 264 } 265} 266 267//------------------------------------------------------------------------------ 268void DInputManager::enumerateDevices() 269{ 270 if ( mDInputInterface ) 271 { 272#ifdef LOG_INPUT 273 Input::log( "Enumerating input devices...\n" ); 274#endif 275 276 DInputDevice::init(); 277 DInputDevice::smDInputInterface = mDInputInterface; 278 mDInputInterface->EnumDevices( DI8DEVTYPE_KEYBOARD, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY ); 279 mDInputInterface->EnumDevices( DI8DEVTYPE_MOUSE, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY ); 280 mDInputInterface->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY ); 281 } 282} 283 284//------------------------------------------------------------------------------ 285BOOL CALLBACK DInputManager::EnumDevicesProc( const DIDEVICEINSTANCE* pddi, LPVOID pvRef ) 286{ 287 DInputManager* manager = (DInputManager*) pvRef; 288 DInputDevice* newDevice = new DInputDevice( pddi ); 289 manager->addObject( newDevice ); 290 if ( !newDevice->create() ) 291 { 292 manager->removeObject( newDevice ); 293 delete newDevice; 294 } 295 296 return (DIENUM_CONTINUE); 297} 298 299//------------------------------------------------------------------------------ 300bool DInputManager::enableJoystick() 301{ 302 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 303 if ( !mgr || !mgr->isEnabled() ) 304 return( false ); 305 306 if ( smJoystickEnabled && mgr->isJoystickActive() ) 307 return( true ); 308 309 smJoystickEnabled = true; 310 if ( Input::isActive() ) 311 smJoystickEnabled = mgr->activateJoystick(); 312 313 if ( smJoystickEnabled ) 314 { 315 Con::printf( "DirectInput joystick enabled." ); 316#ifdef LOG_INPUT 317 Input::log( "Joystick enabled.\n" ); 318#endif 319 } 320 else 321 { 322 Con::warnf( "DirectInput joystick failed to enable!" ); 323#ifdef LOG_INPUT 324 Input::log( "Joystick failed to enable!\n" ); 325#endif 326 } 327 328 return( smJoystickEnabled ); 329} 330 331//------------------------------------------------------------------------------ 332void DInputManager::disableJoystick() 333{ 334 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 335 if ( !mgr || !mgr->isEnabled() || !smJoystickEnabled ) 336 return; 337 338 mgr->deactivateJoystick(); 339 smJoystickEnabled = false; 340 Con::printf( "DirectInput joystick disabled." ); 341#ifdef LOG_INPUT 342 Input::log( "Joystick disabled.\n" ); 343#endif 344} 345 346//------------------------------------------------------------------------------ 347bool DInputManager::isJoystickEnabled() 348{ 349 return( smJoystickEnabled ); 350} 351 352//------------------------------------------------------------------------------ 353bool DInputManager::activateJoystick() 354{ 355 if ( !mEnabled || !Input::isActive() || !smJoystickEnabled ) 356 return( false ); 357 358 mJoystickActive = acquire( JoystickDeviceType, SI_ANY ); 359#ifdef LOG_INPUT 360 Input::log( mJoystickActive ? "Joystick activated.\n" : "Joystick failed to activate!\n" ); 361#endif 362 return( mJoystickActive ); 363} 364 365//------------------------------------------------------------------------------ 366void DInputManager::deactivateJoystick() 367{ 368 if ( mEnabled && mJoystickActive ) 369 { 370 unacquire( JoystickDeviceType, SI_ANY ); 371 mJoystickActive = false; 372#ifdef LOG_INPUT 373 Input::log( "Joystick deactivated.\n" ); 374#endif 375 } 376} 377 378//------------------------------------------------------------------------------ 379const char* DInputManager::getJoystickAxesString( U32 deviceID ) 380{ 381 DInputDevice* dptr; 382 for ( iterator ptr = begin(); ptr != end(); ptr++ ) 383 { 384 dptr = dynamic_cast<DInputDevice*>( *ptr ); 385 if ( dptr && ( dptr->getDeviceType() == JoystickDeviceType ) && ( dptr->getDeviceID() == deviceID ) ) 386 return( dptr->getJoystickAxesString() ); 387 } 388 389 return( "" ); 390} 391 392//------------------------------------------------------------------------------ 393bool DInputManager::enableXInput() 394{ 395 // Largely, this series of functions is identical to the Joystick versions, 396 // except that XInput cannot be "activated" or "deactivated". You either have 397 // the DLL or you don't. Beyond that, you have up to four controllers 398 // connected at any given time 399 400 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 401 if ( !mgr || !mgr->isEnabled() ) 402 return( false ); 403 404 if ( mgr->isXInputActive() ) 405 return( true ); 406 407 if ( Input::isActive() ) 408 mgr->activateXInput(); 409 410 if ( smXInputEnabled ) 411 { 412 Con::printf( "XInput enabled." ); 413#ifdef LOG_INPUT 414 Input::log( "XInput enabled.\n" ); 415#endif 416 } 417 else 418 { 419 Con::warnf( "XInput failed to enable!" ); 420#ifdef LOG_INPUT 421 Input::log( "XInput failed to enable!\n" ); 422#endif 423 } 424 425 return( smXInputEnabled ); 426} 427 428//------------------------------------------------------------------------------ 429void DInputManager::disableXInput() 430{ 431 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 432 if ( !mgr || !mgr->isEnabled()) 433 return; 434 435 mgr->deactivateXInput(); 436 Con::printf( "XInput disabled." ); 437#ifdef LOG_INPUT 438 Input::log( "XInput disabled.\n" ); 439#endif 440} 441 442//------------------------------------------------------------------------------ 443bool DInputManager::isXInputEnabled() 444{ 445 return( smXInputEnabled ); 446} 447 448//------------------------------------------------------------------------------ 449bool DInputManager::isXInputConnected(S32 controllerID) 450{ 451 return( mXInputStateNew[controllerID].bConnected ); 452} 453 454int DInputManager::getXInputState(S32 controllerID, S32 property, bool current) 455{ 456 S32 retVal; 457 458 switch(property) 459 { 460#define CHECK_PROP_ANALOG(prop, stateTest) \ 461 case prop: (current) ? retVal = mXInputStateNew[controllerID].state.Gamepad.stateTest : retVal = mXInputStateOld[controllerID].state.Gamepad.stateTest; return retVal; 462 463 CHECK_PROP_ANALOG(XI_THUMBLX, sThumbLX) 464 CHECK_PROP_ANALOG(XI_THUMBLY, sThumbLY) 465 CHECK_PROP_ANALOG(XI_THUMBRX, sThumbRX) 466 CHECK_PROP_ANALOG(XI_THUMBRY, sThumbRY) 467 CHECK_PROP_ANALOG(XI_LEFT_TRIGGER, bLeftTrigger) 468 CHECK_PROP_ANALOG(XI_RIGHT_TRIGGER, bRightTrigger) 469 470#undef CHECK_PROP_ANALOG 471 472#define CHECK_PROP_DIGITAL(prop, stateTest) \ 473 case prop: (current) ? retVal = (( mXInputStateNew[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ) : retVal = (( mXInputStateOld[controllerID].state.Gamepad.wButtons & stateTest ) != 0 ); return retVal; 474 475 CHECK_PROP_DIGITAL(SI_UPOV, XINPUT_GAMEPAD_DPAD_UP) 476 CHECK_PROP_DIGITAL(SI_DPOV, XINPUT_GAMEPAD_DPAD_DOWN) 477 CHECK_PROP_DIGITAL(SI_LPOV, XINPUT_GAMEPAD_DPAD_LEFT) 478 CHECK_PROP_DIGITAL(SI_RPOV, XINPUT_GAMEPAD_DPAD_RIGHT) 479 CHECK_PROP_DIGITAL(XI_START, XINPUT_GAMEPAD_START) 480 CHECK_PROP_DIGITAL(XI_BACK, XINPUT_GAMEPAD_BACK) 481 CHECK_PROP_DIGITAL(XI_LEFT_THUMB, XINPUT_GAMEPAD_LEFT_THUMB) 482 CHECK_PROP_DIGITAL(XI_RIGHT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB) 483 CHECK_PROP_DIGITAL(XI_LEFT_SHOULDER, XINPUT_GAMEPAD_LEFT_SHOULDER) 484 CHECK_PROP_DIGITAL(XI_RIGHT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER) 485 CHECK_PROP_DIGITAL(XI_A, XINPUT_GAMEPAD_A) 486 CHECK_PROP_DIGITAL(XI_B, XINPUT_GAMEPAD_B) 487 CHECK_PROP_DIGITAL(XI_X, XINPUT_GAMEPAD_X) 488 CHECK_PROP_DIGITAL(XI_Y, XINPUT_GAMEPAD_Y) 489 490#undef CHECK_PROP_DIGITAL 491 } 492 493 return -1; 494} 495 496//------------------------------------------------------------------------------ 497bool DInputManager::activateXInput() 498{ 499 if ( !mEnabled || !Input::isActive()) 500 return( false ); 501 502 mXInputActive = true; //acquire( GamepadDeviceType, SI_ANY ); 503#ifdef LOG_INPUT 504 Input::log( mXInputActive ? "XInput activated.\n" : "XInput failed to activate!\n" ); 505#endif 506 return( mXInputActive ); 507} 508 509//------------------------------------------------------------------------------ 510void DInputManager::deactivateXInput() 511{ 512 if ( mEnabled && mXInputActive ) 513 { 514 unacquire( GamepadDeviceType, SI_ANY ); 515 mXInputActive = false; 516#ifdef LOG_INPUT 517 Input::log( "XInput deactivated.\n" ); 518#endif 519 } 520} 521 522//------------------------------------------------------------------------------ 523bool DInputManager::rumble( const char *pDeviceName, F32 x, F32 y ) 524{ 525 // Determine the device 526 U32 deviceType; 527 U32 deviceInst; 528 529 // Find the requested device 530 if ( !ActionMap::getDeviceTypeAndInstance(pDeviceName, deviceType, deviceInst) ) 531 { 532 Con::printf("DInputManager::rumble: unknown device: %s", pDeviceName); 533 return false; 534 } 535 536 // clamp (x, y) to the range of [0 ... 1] each 537 x = mClampF(x, 0.f, 1.f); 538 y = mClampF(y, 0.f, 1.f); 539 540 // Easy path for xinput devices. 541 if(deviceType == GamepadDeviceType) 542 { 543 XINPUT_VIBRATION vibration; 544 vibration.wLeftMotorSpeed = static_cast<int>(x * 65535); 545 vibration.wRightMotorSpeed = static_cast<int>(y * 65535); 546 return ( mfnXInputSetState(deviceInst, &vibration) == ERROR_SUCCESS ); 547 } 548 549 switch ( deviceType ) 550 { 551 case JoystickDeviceType: 552 553 // Find the device and shake it! 554 DInputDevice* dptr; 555 for ( iterator ptr = begin(); ptr != end(); ptr++ ) 556 { 557 dptr = dynamic_cast<DInputDevice*>( *ptr ); 558 if ( dptr ) 559 { 560 if (deviceType == dptr->getDeviceType() && deviceInst == dptr->getDeviceID()) 561 { 562 dptr->rumble(x, y); 563 return true; 564 } 565 } 566 } 567 568 // We should never get here... something's really messed up 569 Con::errorf( "DInputManager::rumbleJoystick - Couldn't find device to rumble! This should never happen!\n" ); 570 return false; 571 572 default: 573 Con::printf("DInputManager::rumble - only supports joystick and xinput/gamepad devices"); 574 return false; 575 } 576} 577 578void DInputManager::buildXInputEvent( U32 deviceInst, InputEventType objType, InputObjectInstances objInst, InputActionType action, F32 fValue ) 579{ 580 InputEventInfo newEvent; 581 582 newEvent.deviceType = GamepadDeviceType; 583 newEvent.deviceInst = deviceInst; 584 newEvent.objType = objType; 585 newEvent.objInst = objInst; 586 newEvent.action = action; 587 newEvent.fValue = fValue; 588 589 newEvent.postToSignal(Input::smInputEvent); 590} 591 592// The next three functions: fireXInputConnectEvent, fireXInputMoveEvent, and fireXInputButtonEvent 593// determine whether a "delta" has occurred between the last captured controller state and the 594// currently captured controller state and only if so, do we fire an event. The shortcutter 595// "mXInputStateReset" is the exception and is true whenever DirectInput gets reset (because 596// the user ALT-TABBED away, for example). That means that after every context switch, 597// you will get a full set of updates on the "true" state of the controller. 598inline void DInputManager::fireXInputConnectEvent( S32 controllerID, bool condition, bool connected ) 599{ 600 if ( mXInputStateReset || condition ) 601 { 602#ifdef LOG_INPUT 603 Input::log( "EVENT (XInput): xinput%d CONNECT %s\n", controllerID, connected ? "make" : "break" ); 604#endif 605 buildXInputEvent( controllerID, SI_BUTTON, XI_CONNECT, connected ? SI_MAKE : SI_BREAK, 0); 606 } 607} 608 609inline void DInputManager::fireXInputMoveEvent( S32 controllerID, bool condition, InputObjectInstances objInst, F32 fValue ) 610{ 611 if ( mXInputStateReset || condition ) 612 { 613#ifdef LOG_INPUT 614 char *objName; 615 switch (objInst) 616 { 617 case XI_THUMBLX: objName = "THUMBLX"; break; 618 case XI_THUMBLY: objName = "THUMBLY"; break; 619 case XI_THUMBRX: objName = "THUMBRX"; break; 620 case XI_THUMBRY: objName = "THUMBRY"; break; 621 case XI_LEFT_TRIGGER: objName = "LEFT_TRIGGER"; break; 622 case XI_RIGHT_TRIGGER: objName = "RIGHT_TRIGGER"; break; 623 default: objName = "UNKNOWN"; break; 624 } 625 626 Input::log( "EVENT (XInput): xinput%d %s MOVE %.1f.\n", controllerID, objName, fValue ); 627#endif 628 buildXInputEvent( controllerID, SI_AXIS, objInst, SI_MOVE, fValue ); 629 } 630} 631 632inline void DInputManager::fireXInputButtonEvent( S32 controllerID, bool forceFire, S32 button, InputObjectInstances objInst ) 633{ 634 if ( mXInputStateReset || forceFire || ((mXInputStateNew[controllerID].state.Gamepad.wButtons & button) != (mXInputStateOld[controllerID].state.Gamepad.wButtons & button)) ) 635 { 636#ifdef LOG_INPUT 637 char *objName; 638 switch (objInst) 639 { 640 /* 641 case XI_DPAD_UP: objName = "DPAD_UP"; break; 642 case XI_DPAD_DOWN: objName = "DPAD_DOWN"; break; 643 case XI_DPAD_LEFT: objName = "DPAD_LEFT"; break; 644 case XI_DPAD_RIGHT: objName = "DPAD_RIGHT"; break; 645 */ 646 case XI_START: objName = "START"; break; 647 case XI_BACK: objName = "BACK"; break; 648 case XI_LEFT_THUMB: objName = "LEFT_THUMB"; break; 649 case XI_RIGHT_THUMB: objName = "RIGHT_THUMB"; break; 650 case XI_LEFT_SHOULDER: objName = "LEFT_SHOULDER"; break; 651 case XI_RIGHT_SHOULDER: objName = "RIGHT_SHOULDER"; break; 652 case XI_A: objName = "A"; break; 653 case XI_B: objName = "B"; break; 654 case XI_X: objName = "X"; break; 655 case XI_Y: objName = "Y"; break; 656 default: objName = "UNKNOWN"; break; 657 } 658 659 Input::log( "EVENT (XInput): xinput%d %s %s\n", controllerID, objName, ((mXInputStateNew[controllerID].state.Gamepad.wButtons & button) != 0) ? "make" : "break" ); 660#endif 661 InputActionType action = ((mXInputStateNew[controllerID].state.Gamepad.wButtons & button) != 0) ? SI_MAKE : SI_BREAK; 662 buildXInputEvent( controllerID, SI_BUTTON, objInst, action, ( action == SI_MAKE ? 1 : 0 ) ); 663 } 664} 665 666void DInputManager::processXInput( void ) 667{ 668 const U32 curTime = Platform::getRealMilliseconds(); 669 670 // We only want to check one disconnected device per frame. 671 bool foundDisconnected = false; 672 673 if ( mfnXInputGetState ) 674 { 675 for ( S32 i=0; i<4; i++ ) 676 { 677 // Calling XInputGetState on a disconnected controller takes a fair 678 // amount of time (probably because it tries to locate it), so we 679 // add a delay - only check every 250ms or so. 680 if(mLastDisconnectTime[i] != -1) 681 { 682 // If it's not -1, then it was disconnected list time we checked. 683 // So skip until it's time. 684 if((curTime-mLastDisconnectTime[i]) < csmDisconnectedSkipDelay) 685 { 686 continue; 687 } 688 689 // If we already checked a disconnected controller, don't try any 690 // further potentially disconnected devices. 691 if(foundDisconnected) 692 { 693 // If we're skipping this, defer it out by the skip delay 694 // so we don't get clumped checks. 695 mLastDisconnectTime[i] += csmDisconnectedSkipDelay; 696 continue; 697 } 698 } 699 700 mXInputStateOld[i] = mXInputStateNew[i]; 701 mXInputStateNew[i].bConnected = ( mfnXInputGetState( i, &mXInputStateNew[i].state ) == ERROR_SUCCESS ); 702 703 // Update the last connected time. 704 if(mXInputStateNew[i].bConnected) 705 mLastDisconnectTime[i] = -1; 706 else 707 { 708 foundDisconnected = true; 709 mLastDisconnectTime[i] = curTime; 710 } 711 712 // trim the controller's thumbsticks to zero if they are within the deadzone 713 if( mXInputDeadZoneOn ) 714 { 715 // Zero value if thumbsticks are within the dead zone 716 if( (mXInputStateNew[i].state.Gamepad.sThumbLX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLX > -XINPUT_DEADZONE) && 717 (mXInputStateNew[i].state.Gamepad.sThumbLY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLY > -XINPUT_DEADZONE) ) 718 { 719 mXInputStateNew[i].state.Gamepad.sThumbLX = 0; 720 mXInputStateNew[i].state.Gamepad.sThumbLY = 0; 721 } 722 723 if( (mXInputStateNew[i].state.Gamepad.sThumbRX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRX > -XINPUT_DEADZONE) && 724 (mXInputStateNew[i].state.Gamepad.sThumbRY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRY > -XINPUT_DEADZONE) ) 725 { 726 mXInputStateNew[i].state.Gamepad.sThumbRX = 0; 727 mXInputStateNew[i].state.Gamepad.sThumbRY = 0; 728 } 729 } 730 731 // this controller was connected or disconnected 732 bool bJustConnected = ( ( mXInputStateOld[i].bConnected != mXInputStateNew[i].bConnected ) && ( mXInputStateNew[i].bConnected ) ); 733 fireXInputConnectEvent( i, (mXInputStateOld[i].bConnected != mXInputStateNew[i].bConnected), mXInputStateNew[i].bConnected ); 734 735 // If this controller is disconnected, stop reporting events for it 736 if ( !mXInputStateNew[i].bConnected ) 737 continue; 738 739 // == LEFT THUMBSTICK == 740 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.sThumbLX != mXInputStateOld[i].state.Gamepad.sThumbLX), XI_THUMBLX, (mXInputStateNew[i].state.Gamepad.sThumbLX / 32768.0f) ); 741 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.sThumbLY != mXInputStateOld[i].state.Gamepad.sThumbLY), XI_THUMBLY, (mXInputStateNew[i].state.Gamepad.sThumbLY / 32768.0f) ); 742 743 // == RIGHT THUMBSTICK == 744 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.sThumbRX != mXInputStateOld[i].state.Gamepad.sThumbRX), XI_THUMBRX, (mXInputStateNew[i].state.Gamepad.sThumbRX / 32768.0f) ); 745 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.sThumbRY != mXInputStateOld[i].state.Gamepad.sThumbRY), XI_THUMBRY, (mXInputStateNew[i].state.Gamepad.sThumbRY / 32768.0f) ); 746 747 // == LEFT & RIGHT REAR TRIGGERS == 748 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.bLeftTrigger != mXInputStateOld[i].state.Gamepad.bLeftTrigger), XI_LEFT_TRIGGER, (mXInputStateNew[i].state.Gamepad.bLeftTrigger / 255.0f) ); 749 fireXInputMoveEvent( i, ( bJustConnected ) || (mXInputStateNew[i].state.Gamepad.bRightTrigger != mXInputStateOld[i].state.Gamepad.bRightTrigger), XI_RIGHT_TRIGGER, (mXInputStateNew[i].state.Gamepad.bRightTrigger / 255.0f) ); 750 751 // == BUTTONS: DPAD == 752 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_DPAD_UP, SI_UPOV ); 753 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_DPAD_DOWN, SI_DPOV ); 754 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_DPAD_LEFT, SI_LPOV ); 755 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_DPAD_RIGHT, SI_RPOV ); 756 757 // == BUTTONS: START & BACK == 758 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_START, XI_START ); 759 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_BACK, XI_BACK ); 760 761 // == BUTTONS: LEFT AND RIGHT THUMBSTICK == 762 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_LEFT_THUMB, XI_LEFT_THUMB ); 763 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_RIGHT_THUMB, XI_RIGHT_THUMB ); 764 765 // == BUTTONS: LEFT AND RIGHT SHOULDERS (formerly WHITE and BLACK on Xbox 1) == 766 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_LEFT_SHOULDER, XI_LEFT_SHOULDER ); 767 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_RIGHT_SHOULDER, XI_RIGHT_SHOULDER ); 768 769 // == BUTTONS: A, B, X, and Y == 770 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_A, XI_A ); 771 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_B, XI_B ); 772 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_X, XI_X ); 773 fireXInputButtonEvent( i, bJustConnected, XINPUT_GAMEPAD_Y, XI_Y ); 774 } 775 776 if ( mXInputStateReset ) 777 mXInputStateReset = false; 778 } 779} 780DefineEngineFunction( enableJoystick, bool, (), , "()" 781 "@brief Enables use of the joystick.\n\n" 782 "@note DirectInput must be enabled and active to use this function.\n\n" 783 "@ingroup Input") 784{ 785 return( DInputManager::enableJoystick() ); 786} 787 788//------------------------------------------------------------------------------ 789DefineEngineFunction( disableJoystick, void, (), , "()" 790 "@brief Disables use of the joystick.\n\n" 791 "@note DirectInput must be enabled and active to use this function.\n\n" 792 "@ingroup Input") 793{ 794 DInputManager::disableJoystick(); 795} 796 797//------------------------------------------------------------------------------ 798DefineEngineFunction( isJoystickEnabled, bool, (), , "()" 799 "@brief Queries input manager to see if a joystick is enabled\n\n" 800 "@return 1 if a joystick exists and is enabled, 0 if it's not.\n" 801 "@ingroup Input") 802{ 803 return DInputManager::isJoystickEnabled(); 804} 805 806//------------------------------------------------------------------------------ 807DefineEngineFunction( enableXInput, bool, (), , "()" 808 "@brief Enables XInput for Xbox 360 controllers.\n\n" 809 "@note XInput is enabled by default. Disable to use an Xbox 360 " 810 "Controller as a joystick device.\n\n" 811 "@ingroup Input") 812{ 813 // Although I said above that you couldn't change the "activation" of XInput, 814 // you can enable and disable it. It gets enabled by default if you have the 815 // DLL. You would want to disable it if you have 360 controllers and want to 816 // read them as joysticks... why you'd want to do that is beyond me 817 818 return( DInputManager::enableXInput() ); 819} 820 821//------------------------------------------------------------------------------ 822DefineEngineFunction( disableXInput, void, (), , "()" 823 "@brief Disables XInput for Xbox 360 controllers.\n\n" 824 "@ingroup Input") 825{ 826 DInputManager::disableXInput(); 827} 828 829//------------------------------------------------------------------------------ 830DefineEngineFunction( resetXInput, void, (), , "()" 831 "@brief Rebuilds the XInput section of the InputManager\n\n" 832 "Requests a full refresh of events for all controllers. Useful when called at the beginning " 833 "of game code after actionMaps are set up to hook up all appropriate events.\n\n" 834 "@ingroup Input") 835{ 836 // This function requests a full "refresh" of events for all controllers the 837 // next time we go through the input processing loop. This is useful to call 838 // at the beginning of your game code after your actionMap is set up to hook 839 // all of the appropriate events 840 841 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 842 if ( mgr && mgr->isEnabled() ) 843 mgr->resetXInput(); 844} 845 846//------------------------------------------------------------------------------ 847DefineEngineFunction( isXInputConnected, bool, (S32 controllerID), , "( int controllerID )" 848 "@brief Checks to see if an Xbox 360 controller is connected\n\n" 849 "@param controllerID Zero-based index of the controller to check.\n" 850 "@return 1 if the controller is connected, 0 if it isn't, and 205 if XInput " 851 "hasn't been initialized." 852 "@ingroup Input") 853{ 854 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 855 if ( mgr && mgr->isEnabled() ) return mgr->isXInputConnected( controllerID ); 856 return false; 857} 858 859//------------------------------------------------------------------------------ 860DefineEngineFunction( getXInputState, int, (S32 controllerID, const char * properties, bool current), (false), "( int controllerID, string property, bool currentD )" 861 "@brief Queries the current state of a connected Xbox 360 controller.\n\n" 862 "XInput Properties:\n\n" 863 " - XI_THUMBLX, XI_THUMBLY - X and Y axes of the left thumbstick. \n" 864 " - XI_THUMBRX, XI_THUMBRY - X and Y axes of the right thumbstick. \n" 865 " - XI_LEFT_TRIGGER, XI_RIGHT_TRIGGER - Left and Right triggers. \n" 866 " - SI_UPOV, SI_DPOV, SI_LPOV, SI_RPOV - Up, Down, Left, and Right on the directional pad.\n" 867 " - XI_START, XI_BACK - The Start and Back buttons.\n" 868 " - XI_LEFT_THUMB, XI_RIGHT_THUMB - Clicking in the left and right thumbstick.\n" 869 " - XI_LEFT_SHOULDER, XI_RIGHT_SHOULDER - Left and Right bumpers.\n" 870 " - XI_A, XI_B , XI_X, XI_Y - The A, B, X, and Y buttons.\n\n" 871 "@param controllerID Zero-based index of the controller to return information about.\n" 872 "@param property Name of input action being queried, such as \"XI_THUMBLX\".\n" 873 "@param current True checks current device in action.\n" 874 "@return Button queried - 1 if the button is pressed, 0 if it's not.\n" 875 "@return Thumbstick queried - Int representing displacement from rest position." 876 "@return %Trigger queried - Int from 0 to 255 representing how far the trigger is displaced." 877 "@ingroup Input") 878{ 879 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 880 881 if ( !mgr || !mgr->isEnabled() ) 882 return -1; 883 884 // Use a little bit of macro magic to simplify this otherwise monolothic 885 // block of code. 886#define GET_XI_STATE(constName) \ 887 if (!dStricmp(properties, #constName)) \ 888 return mgr->getXInputState( controllerID, constName, ( current )); 889 890 GET_XI_STATE(XI_THUMBLX); 891 GET_XI_STATE(XI_THUMBLY); 892 GET_XI_STATE(XI_THUMBRX); 893 GET_XI_STATE(XI_THUMBRY); 894 GET_XI_STATE(XI_LEFT_TRIGGER); 895 GET_XI_STATE(XI_RIGHT_TRIGGER); 896 GET_XI_STATE(SI_UPOV); 897 GET_XI_STATE(SI_DPOV); 898 GET_XI_STATE(SI_LPOV); 899 GET_XI_STATE(SI_RPOV); 900 GET_XI_STATE(XI_START); 901 GET_XI_STATE(XI_BACK); 902 GET_XI_STATE(XI_LEFT_THUMB); 903 GET_XI_STATE(XI_RIGHT_THUMB); 904 GET_XI_STATE(XI_LEFT_SHOULDER); 905 GET_XI_STATE(XI_RIGHT_SHOULDER); 906 GET_XI_STATE(XI_A); 907 GET_XI_STATE(XI_B); 908 GET_XI_STATE(XI_X); 909 GET_XI_STATE(XI_Y); 910#undef GET_XI_STATE 911 912 return -1; 913} 914 915//------------------------------------------------------------------------------ 916DefineEngineFunction( echoInputState, void, (), , "()" 917 "@brief Prints information to the console stating if DirectInput and a Joystick are enabled and active.\n\n" 918 "@ingroup Input") 919{ 920 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 921 if ( mgr && mgr->isEnabled() ) 922 { 923 Con::printf( "DirectInput is enabled %s.", Input::isActive() ? "and active" : "but inactive" ); 924 Con::printf( "- Joystick is %sabled and %sactive.", 925 mgr->isJoystickEnabled() ? "en" : "dis", 926 mgr->isJoystickActive() ? "" : "in" ); 927 } 928 else 929 Con::printf( "DirectInput is not enabled." ); 930} 931 932DefineEngineFunction( rumble, void, (const char * device, F32 xRumble, F32 yRumble), , "(string device, float xRumble, float yRumble)" 933 "@brief Activates the vibration motors in the specified controller.\n\n" 934 "The controller will constantly at it's xRumble and yRumble intensities until " 935 "changed or told to stop." 936 "Valid inputs for xRumble/yRumble are [0 - 1].\n" 937 "@param device Name of the device to rumble.\n" 938 "@param xRumble Intensity to apply to the left motor.\n" 939 "@param yRumble Intensity to apply to the right motor.\n" 940 "@note in an Xbox 360 controller, the left motor is low-frequency, " 941 "while the right motor is high-frequency." 942 "@ingroup Input") 943{ 944 DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() ); 945 if ( mgr && mgr->isEnabled() ) 946 { 947 mgr->rumble(device, xRumble, yRumble); 948 } 949 else 950 { 951 Con::printf( "DirectInput/XInput is not enabled." ); 952 } 953} 954