InputDeviceVirtualGamepad.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "InputDeviceVirtualGamepad.h"
  9. #include "VirtualGamepadButtonRequestBus.h"
  10. #include "VirtualGamepadThumbStickRequestBus.h"
  11. #include <AzFramework/Input/Devices/Touch/InputDeviceTouch.h>
  12. ////////////////////////////////////////////////////////////////////////////////////////////////////
  13. namespace VirtualGamepad
  14. {
  15. using namespace AzFramework;
  16. ////////////////////////////////////////////////////////////////////////////////////////////////
  17. const InputDeviceId InputDeviceVirtualGamepad::Id("virtual_gamepad");
  18. ////////////////////////////////////////////////////////////////////////////////////////////////
  19. bool InputDeviceVirtualGamepad::IsVirtualGamepadDevice(const InputDeviceId& inputDeviceId)
  20. {
  21. return (inputDeviceId.GetNameCrc32() == Id.GetNameCrc32());
  22. }
  23. ////////////////////////////////////////////////////////////////////////////////////////////////
  24. InputDeviceVirtualGamepad::InputDeviceVirtualGamepad(
  25. const AZStd::unordered_set<AZStd::string>& buttonNames,
  26. const AZStd::unordered_set<AZStd::string>& thumbStickNames)
  27. : InputDevice(Id)
  28. , m_allChannelsById()
  29. , m_buttonChannelsByName()
  30. , m_thumbStickAxis1DChannelsByName()
  31. , m_thumbStickAxis2DChannelsByName()
  32. , m_thumbStickDirectionChannelsByName()
  33. {
  34. // Create all button input channels
  35. for (const AZStd::string& buttonName : buttonNames)
  36. {
  37. CreateButtonChannel(buttonName);
  38. }
  39. // Create all thumb-stick input channels
  40. for (const AZStd::string& thumbStickName : thumbStickNames)
  41. {
  42. CreateThumbStickAxis2DChannel(thumbStickName);
  43. CreateThumbStickAxis1DChannel(thumbStickName + "_x");
  44. CreateThumbStickAxis1DChannel(thumbStickName + "_y");
  45. CreateThumbStickDirectionChannel(thumbStickName + "_u");
  46. CreateThumbStickDirectionChannel(thumbStickName + "_d");
  47. CreateThumbStickDirectionChannel(thumbStickName + "_l");
  48. CreateThumbStickDirectionChannel(thumbStickName + "_r");
  49. }
  50. }
  51. ////////////////////////////////////////////////////////////////////////////////////////////////
  52. InputDeviceVirtualGamepad::~InputDeviceVirtualGamepad()
  53. {
  54. // Destroy all thumb-stick direction input channels
  55. for (const auto& channelByName : m_thumbStickDirectionChannelsByName)
  56. {
  57. delete channelByName.second;
  58. }
  59. // Destroy all thumb-stick 2D axis input channels
  60. for (const auto& channelByName : m_thumbStickAxis2DChannelsByName)
  61. {
  62. delete channelByName.second;
  63. }
  64. // Destroy all thumb-stick 1D axis input channels
  65. for (const auto& channelByName : m_thumbStickAxis1DChannelsByName)
  66. {
  67. delete channelByName.second;
  68. }
  69. // Destroy all button input channels
  70. for (const auto& channelByName : m_buttonChannelsByName)
  71. {
  72. delete channelByName.second;
  73. }
  74. }
  75. ////////////////////////////////////////////////////////////////////////////////////////////////
  76. const InputDevice::InputChannelByIdMap& InputDeviceVirtualGamepad::GetInputChannelsById() const
  77. {
  78. return m_allChannelsById;
  79. }
  80. ////////////////////////////////////////////////////////////////////////////////////////////////
  81. bool InputDeviceVirtualGamepad::IsSupported() const
  82. {
  83. // Touch input must be supported
  84. const InputDevice* inputDevice = nullptr;
  85. InputDeviceRequestBus::EventResult(inputDevice,
  86. InputDeviceTouch::Id,
  87. &InputDeviceRequests::GetInputDevice);
  88. return inputDevice && inputDevice->IsSupported();
  89. }
  90. ////////////////////////////////////////////////////////////////////////////////////////////////
  91. bool InputDeviceVirtualGamepad::IsConnected() const
  92. {
  93. // Touch input must be connected
  94. const InputDevice* inputDevice = nullptr;
  95. InputDeviceRequestBus::EventResult(inputDevice,
  96. InputDeviceTouch::Id,
  97. &InputDeviceRequests::GetInputDevice);
  98. return inputDevice && inputDevice->IsConnected();
  99. }
  100. ////////////////////////////////////////////////////////////////////////////////////////////////
  101. void InputDeviceVirtualGamepad::TickInputDevice()
  102. {
  103. for (const auto& buttonChannelByName : m_buttonChannelsByName)
  104. {
  105. bool isButtonPressed = false;
  106. VirtualGamepadButtonRequestBus::EventResult(isButtonPressed,
  107. buttonChannelByName.first,
  108. &VirtualGamepadButtonRequests::IsPressed);
  109. buttonChannelByName.second->ProcessRawInputEvent(isButtonPressed);
  110. }
  111. for (const auto& thumbStickAxis2DChannelByName : m_thumbStickAxis2DChannelsByName)
  112. {
  113. const AZStd::string& thumbStickName = thumbStickAxis2DChannelByName.first;
  114. AZ::Vector2 axisValues(0.0f, 0.0f);
  115. VirtualGamepadThumbStickRequestBus::EventResult(axisValues,
  116. thumbStickName,
  117. &VirtualGamepadThumbStickRequests::GetCurrentAxisValuesNormalized);
  118. thumbStickAxis2DChannelByName.second->ProcessRawInputEvent(axisValues);
  119. m_thumbStickAxis1DChannelsByName[thumbStickName + "_x"]->ProcessRawInputEvent(axisValues.GetX());
  120. m_thumbStickAxis1DChannelsByName[thumbStickName + "_y"]->ProcessRawInputEvent(axisValues.GetY());
  121. const float upValue = AZ::GetClamp(axisValues.GetY(), 0.0f, 1.0f);
  122. const float downValue = AZ::GetClamp(axisValues.GetY(), -1.0f, 0.0f);
  123. const float leftValue = AZ::GetClamp(axisValues.GetX(), -1.0f, 0.0f);
  124. const float rightValue = AZ::GetClamp(axisValues.GetX(), 0.0f, 1.0f);
  125. m_thumbStickDirectionChannelsByName[thumbStickName + "_u"]->ProcessRawInputEvent(upValue);
  126. m_thumbStickDirectionChannelsByName[thumbStickName + "_d"]->ProcessRawInputEvent(downValue);
  127. m_thumbStickDirectionChannelsByName[thumbStickName + "_l"]->ProcessRawInputEvent(leftValue);
  128. m_thumbStickDirectionChannelsByName[thumbStickName + "_r"]->ProcessRawInputEvent(rightValue);
  129. }
  130. }
  131. ////////////////////////////////////////////////////////////////////////////////////////////////
  132. void InputDeviceVirtualGamepad::CreateButtonChannel(const AZStd::string& channelName)
  133. {
  134. const InputChannelId channelId(channelName.c_str());
  135. InputChannelDigital* channel = aznew InputChannelDigital(channelId, *this);
  136. m_allChannelsById[channelId] = channel;
  137. m_buttonChannelsByName[channelName] = channel;
  138. }
  139. ////////////////////////////////////////////////////////////////////////////////////////////////
  140. void InputDeviceVirtualGamepad::CreateThumbStickAxis1DChannel(const AZStd::string& channelName)
  141. {
  142. const InputChannelId channelId(channelName.c_str());
  143. InputChannelAxis1D* channel = aznew InputChannelAxis1D(channelId, *this);
  144. m_allChannelsById[channelId] = channel;
  145. m_thumbStickAxis1DChannelsByName[channelName] = channel;
  146. }
  147. ////////////////////////////////////////////////////////////////////////////////////////////////
  148. void InputDeviceVirtualGamepad::CreateThumbStickAxis2DChannel(const AZStd::string& channelName)
  149. {
  150. const InputChannelId channelId(channelName.c_str());
  151. InputChannelAxis2D* channel = aznew InputChannelAxis2D(channelId, *this);
  152. m_allChannelsById[channelId] = channel;
  153. m_thumbStickAxis2DChannelsByName[channelName] = channel;
  154. }
  155. ////////////////////////////////////////////////////////////////////////////////////////////////
  156. void InputDeviceVirtualGamepad::CreateThumbStickDirectionChannel(const AZStd::string& channelName)
  157. {
  158. const InputChannelId channelId(channelName.c_str());
  159. InputChannelAnalog* channel = aznew InputChannelAnalog(channelId, *this);
  160. m_allChannelsById[channelId] = channel;
  161. m_thumbStickDirectionChannelsByName[channelName] = channel;
  162. }
  163. } // namespace VirtualGamepad