input_device.cpp 3.7 KB

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