input_device.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "allocator.h"
  6. #include "error.h"
  7. #include "input_device.h"
  8. #include "memory.h"
  9. #include "string_id.h"
  10. #include "string_utils.h"
  11. #include <string.h> // strcpy, memset
  12. namespace crown
  13. {
  14. const char* InputDevice::name() const
  15. {
  16. return _name;
  17. }
  18. bool InputDevice::connected() const
  19. {
  20. return _connected;
  21. }
  22. u8 InputDevice::num_buttons() const
  23. {
  24. return _num_buttons;
  25. }
  26. u8 InputDevice::num_axes() const
  27. {
  28. return _num_axes;
  29. }
  30. bool InputDevice::pressed(u8 id) const
  31. {
  32. return id < _num_buttons
  33. ? (~_last_state[id] & _state[id]) != 0
  34. : false
  35. ;
  36. }
  37. bool InputDevice::released(u8 id) const
  38. {
  39. return id < _num_buttons
  40. ? (_last_state[id] & ~_state[id]) != 0
  41. : false
  42. ;
  43. }
  44. bool InputDevice::any_pressed() const
  45. {
  46. return pressed(_last_button);
  47. }
  48. bool InputDevice::any_released() const
  49. {
  50. return released(_last_button);
  51. }
  52. Vector3 InputDevice::axis(u8 id) const
  53. {
  54. return id < _num_axes
  55. ? _axis[id]
  56. : VECTOR3_ZERO
  57. ;
  58. }
  59. const char* InputDevice::button_name(u8 id)
  60. {
  61. return id < _num_buttons
  62. ? _button_name[id]
  63. : NULL
  64. ;
  65. }
  66. const char* InputDevice::axis_name(u8 id)
  67. {
  68. return id < _num_axes
  69. ? _axis_name[id]
  70. : NULL
  71. ;
  72. }
  73. u8 InputDevice::button_id(StringId32 name)
  74. {
  75. for (u32 i = 0; i < _num_buttons; ++i)
  76. {
  77. if (_button_hash[i] == name)
  78. return i;
  79. }
  80. return UINT8_MAX;
  81. }
  82. u8 InputDevice::axis_id(StringId32 name)
  83. {
  84. for (u32 i = 0; i < _num_axes; ++i)
  85. {
  86. if (_axis_hash[i] == name)
  87. return i;
  88. }
  89. return UINT8_MAX;
  90. }
  91. void InputDevice::set_connected(bool connected)
  92. {
  93. _connected = connected;
  94. }
  95. void InputDevice::set_button_state(u8 i, bool state)
  96. {
  97. CE_ASSERT(i < _num_buttons, "Index out of bounds");
  98. _last_button = i;
  99. _state[i] = state;
  100. }
  101. void InputDevice::set_axis(u8 i, const Vector3& value)
  102. {
  103. CE_ASSERT(i < _num_axes, "Index out of bounds");
  104. _axis[i] = value;
  105. }
  106. void InputDevice::update()
  107. {
  108. memcpy(_last_state, _state, sizeof(u8)*_num_buttons);
  109. }
  110. namespace input_device
  111. {
  112. InputDevice* create(Allocator& a, const char* name, u8 num_buttons, u8 num_axes, const char** button_names, const char** axis_names)
  113. {
  114. const u32 size = 0
  115. + sizeof(InputDevice) + alignof(InputDevice)
  116. + sizeof(u8)*num_buttons*2 + alignof(u8)
  117. + sizeof(Vector3)*num_axes + alignof(Vector3)
  118. + sizeof(char*)*num_buttons + alignof(char*)
  119. + sizeof(char*)*num_axes + alignof(char*)
  120. + sizeof(StringId32)*num_buttons + alignof(StringId32)
  121. + sizeof(StringId32)*num_axes + alignof(StringId32)
  122. + strlen32(name) + 1 + alignof(char)
  123. ;
  124. InputDevice* id = (InputDevice*)a.allocate(size);
  125. id->_connected = false;
  126. id->_num_buttons = num_buttons;
  127. id->_num_axes = num_axes;
  128. id->_last_button = 0;
  129. id->_last_state = (u8* )&id[1];
  130. id->_state = (u8* )memory::align_top(id->_last_state + num_buttons, alignof(u8 ));
  131. id->_axis = (Vector3* )memory::align_top(id->_state + num_buttons, alignof(Vector3 ));
  132. id->_button_name = (const char**)memory::align_top(id->_axis + num_axes, alignof(const char*));
  133. id->_axis_name = (const char**)memory::align_top(id->_button_name + num_buttons, alignof(const char*));
  134. id->_button_hash = (StringId32* )memory::align_top(id->_axis_name + num_axes, alignof(StringId32 ));
  135. id->_axis_hash = (StringId32* )memory::align_top(id->_button_hash + num_buttons, alignof(StringId32 ));
  136. id->_name = (char* )memory::align_top(id->_axis_hash + num_axes, alignof(char ));
  137. memset(id->_last_state, 0, sizeof(u8)*num_buttons);
  138. memset(id->_state, 0, sizeof(u8)*num_buttons);
  139. memset(id->_axis, 0, sizeof(Vector3)*num_axes);
  140. memcpy(id->_button_name, button_names, sizeof(const char*)*num_buttons);
  141. memcpy(id->_axis_name, axis_names, sizeof(const char*)*num_axes);
  142. for (u32 i = 0; i < num_buttons; ++i)
  143. id->_button_hash[i] = StringId32(button_names[i]);
  144. for (u32 i = 0; i < num_axes; ++i)
  145. id->_axis_hash[i] = StringId32(axis_names[i]);
  146. strcpy(id->_name, name);
  147. return id;
  148. }
  149. void destroy(Allocator& a, InputDevice& id)
  150. {
  151. a.deallocate(&id);
  152. }
  153. } // namespace input_device
  154. } // namespace crown