BsInputHandlerOIS.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "BsInputHandlerOIS.h"
  2. #include "BsVector2I.h"
  3. #include "OIS/OISException.h"
  4. #include "BsRenderWindow.h"
  5. #include "BsTime.h"
  6. #include "BsMath.h"
  7. #include "BsDebug.h"
  8. namespace BansheeEngine
  9. {
  10. const UINT32 InputHandlerOIS::MOUSE_SENSITIVITY = 1;
  11. GamepadEventListener::GamepadEventListener(InputHandlerOIS* parentHandler, UINT32 joystickIdx)
  12. :mParentHandler(parentHandler), mGamepadIdx(joystickIdx)
  13. { }
  14. bool GamepadEventListener::buttonPressed(const OIS::JoyStickEvent& arg, int button)
  15. {
  16. ButtonCode bc = InputHandlerOIS::gamepadButtonToButtonCode(button);
  17. // Note: No timestamps for gamepad buttons, but they shouldn't be used for anything anyway
  18. mParentHandler->onButtonDown(mGamepadIdx, bc, 0);
  19. return true;
  20. }
  21. bool GamepadEventListener::buttonReleased(const OIS::JoyStickEvent& arg, int button)
  22. {
  23. ButtonCode bc = InputHandlerOIS::gamepadButtonToButtonCode(button);
  24. // Note: No timestamps for gamepad buttons, but they shouldn't be used for anything anyway
  25. mParentHandler->onButtonUp(mGamepadIdx, bc, 0);
  26. return true;
  27. }
  28. bool GamepadEventListener::axisMoved(const OIS::JoyStickEvent& arg, int axis)
  29. {
  30. // Move axis values into [-1.0f, 1.0f] range
  31. float axisRange = Math::abs((float)OIS::JoyStick::MAX_AXIS) + Math::abs((float)OIS::JoyStick::MIN_AXIS);
  32. INT32 axisRel = arg.state.mAxes[axis].rel;
  33. INT32 axisAbs = arg.state.mAxes[axis].abs;
  34. RawAxisState axisState;
  35. axisState.rel = ((axisRel + Math::abs((float)OIS::JoyStick::MIN_AXIS)) / axisRange) * 2.0f - 1.0f;
  36. axisState.abs = ((axisAbs + Math::abs((float)OIS::JoyStick::MIN_AXIS)) / axisRange) * 2.0f - 1.0f;
  37. mParentHandler->onAxisMoved(mGamepadIdx, axisState, (UINT32)axis);
  38. LOGWRN(toString(axis) + " - " + toString(axisState.abs));
  39. return true;
  40. }
  41. InputHandlerOIS::InputHandlerOIS(unsigned int hWnd)
  42. :mInputManager(nullptr), mKeyboard(nullptr), mMouse(nullptr), mTimestampClockOffset(0)
  43. {
  44. OIS::ParamList pl;
  45. std::ostringstream windowHndStr;
  46. windowHndStr << hWnd;
  47. pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
  48. #if defined BS_PLATFORM == BS_PLATFORM_WIN32
  49. pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
  50. pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
  51. pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
  52. pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
  53. #elif defined BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_APPLE
  54. pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
  55. pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
  56. pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
  57. pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
  58. #endif
  59. try
  60. {
  61. mInputManager = OIS::InputManager::createInputSystem(pl);
  62. }
  63. catch(OIS::Exception &e)
  64. {
  65. std::cout << e.eText << std::endl;
  66. }
  67. if (mInputManager->getNumberOfDevices(OIS::OISKeyboard) > 0)
  68. {
  69. mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
  70. mKeyboard->setEventCallback(this);
  71. }
  72. if (mInputManager->getNumberOfDevices(OIS::OISMouse) > 0)
  73. {
  74. mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));
  75. mMouse->setEventCallback(this);
  76. }
  77. UINT32 numGamepads = mInputManager->getNumberOfDevices(OIS::OISJoyStick);
  78. for (UINT32 i = 0; i < numGamepads; i++)
  79. {
  80. mGamepads.push_back(GamepadData());
  81. GamepadData& gamepadData = mGamepads.back();
  82. gamepadData.gamepad = static_cast<OIS::JoyStick*>(mInputManager->createInputObject(OIS::OISJoyStick, true));
  83. gamepadData.listener = bs_new<GamepadEventListener>(this, i);
  84. gamepadData.gamepad->setEventCallback(gamepadData.listener);
  85. }
  86. // OIS reports times since system start but we use time since program start
  87. mTimestampClockOffset = gTime().getStartTimeMs();
  88. }
  89. InputHandlerOIS::~InputHandlerOIS()
  90. {
  91. if(mInputManager)
  92. {
  93. if(mMouse != nullptr)
  94. mInputManager->destroyInputObject(mMouse);
  95. if(mKeyboard != nullptr)
  96. mInputManager->destroyInputObject(mKeyboard);
  97. for (auto& gamepadData : mGamepads)
  98. {
  99. mInputManager->destroyInputObject(gamepadData.gamepad);
  100. bs_delete(gamepadData.listener);
  101. }
  102. OIS::InputManager::destroyInputSystem(mInputManager);
  103. mInputManager = nullptr;
  104. }
  105. }
  106. void InputHandlerOIS::_update()
  107. {
  108. if (mMouse != nullptr)
  109. mMouse->capture();
  110. if (mKeyboard != nullptr)
  111. mKeyboard->capture();
  112. for (auto& gamepadData : mGamepads)
  113. {
  114. gamepadData.gamepad->capture();
  115. }
  116. }
  117. void InputHandlerOIS::_inputWindowChanged(const RenderWindow& win)
  118. {
  119. unsigned long long hWnd;
  120. win.getCustomAttribute("WINDOW", &hWnd);
  121. std::string normalString = toString((UINT64)hWnd).c_str();
  122. mKeyboard->setCaptureContext(normalString);
  123. mMouse->setCaptureContext(normalString);
  124. }
  125. bool InputHandlerOIS::keyPressed(const OIS::KeyEvent &arg)
  126. {
  127. onButtonDown(0, keyCodeToButtonCode(arg.key), arg.timestamp - mTimestampClockOffset);
  128. return true;
  129. }
  130. bool InputHandlerOIS::keyReleased(const OIS::KeyEvent& arg)
  131. {
  132. onButtonUp(0, keyCodeToButtonCode(arg.key), arg.timestamp - mTimestampClockOffset);
  133. return true;
  134. }
  135. bool InputHandlerOIS::mouseMoved(const OIS::MouseEvent& arg)
  136. {
  137. RawAxisState xState;
  138. xState.rel = Math::clamp(arg.state.X.rel / (float)MOUSE_SENSITIVITY, -1.0f, 1.0f);
  139. xState.abs = xState.rel; // Abs value irrelevant for mouse
  140. onAxisMoved(0, xState, (UINT32)InputAxis::MouseX);
  141. RawAxisState yState;
  142. yState.rel = Math::clamp(arg.state.Y.rel / (float)MOUSE_SENSITIVITY, -1.0f, 1.0f);
  143. yState.abs = yState.rel; // Abs value irrelevant for mouse
  144. onAxisMoved(0, yState, (UINT32)InputAxis::MouseY);
  145. RawAxisState zState;
  146. zState.abs = (float)arg.state.Z.abs;
  147. zState.rel = (float)arg.state.Z.rel;
  148. onAxisMoved(0, zState, (UINT32)InputAxis::MouseZ);
  149. return true;
  150. }
  151. bool InputHandlerOIS::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
  152. {
  153. onButtonDown(0, mouseButtonToButtonCode(id), arg.timestamp - mTimestampClockOffset);
  154. return true;
  155. }
  156. bool InputHandlerOIS::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
  157. {
  158. onButtonUp(0, mouseButtonToButtonCode(id), arg.timestamp - mTimestampClockOffset);
  159. return true;
  160. }
  161. ButtonCode InputHandlerOIS::keyCodeToButtonCode(OIS::KeyCode keyCode)
  162. {
  163. return (ButtonCode)keyCode;
  164. }
  165. ButtonCode InputHandlerOIS::mouseButtonToButtonCode(OIS::MouseButtonID mouseBtn)
  166. {
  167. return (ButtonCode)(((int)mouseBtn + BC_NumKeys) | 0x80000000);
  168. }
  169. ButtonCode InputHandlerOIS::gamepadButtonToButtonCode(INT32 joystickCode)
  170. {
  171. switch (joystickCode)
  172. {
  173. case 0:
  174. return BC_GAMEPAD_A;
  175. case 1:
  176. return BC_GAMEPAD_B;
  177. case 2:
  178. return BC_GAMEPAD_X;
  179. case 3:
  180. return BC_GAMEPAD_Y;
  181. case 4:
  182. return BC_GAMEPAD_LB;
  183. case 5:
  184. return BC_GAMEPAD_RB;
  185. case 6:
  186. return BC_GAMEPAD_BACK;
  187. case 7:
  188. return BC_GAMEPAD_START;
  189. case 8:
  190. return BC_GAMEPAD_BTN1;
  191. case 9:
  192. return BC_GAMEPAD_RS;
  193. case 10:
  194. return BC_GAMEPAD_BTN2;
  195. case 11:
  196. return BC_GAMEPAD_LS;
  197. }
  198. return (ButtonCode)(BC_GAMEPAD_BTN3 + (joystickCode - 11));
  199. }
  200. }