Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
input_state.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef INPUT_CONTROLLER_H
20 #define INPUT_CONTROLLER_H
21 
22 #include <cstdint>
23 #include <vector>
24 #include <map>
25 #include <functional>
26 #include <set>
27 #include <cassert>
28 
29 #include "../keycodes.h"
30 #include "../types.h"
31 
32 #include "../signals/signal.h"
33 #include "../generic/managed.h"
34 #include "../generic/identifiable.h"
35 #include "../generic/unique_id.h"
36 
37 namespace smlt {
38 
39 class InputState;
40 
42  uint32_t id;
43  std::string name;
44  uint8_t button_count;
45  uint8_t axis_count;
46  uint8_t hat_count;
47 };
48 
50  uint32_t id;
51 };
52 
54  uint32_t id;
55  uint8_t button_count;
56  uint8_t axis_count;
57 };
58 
59 
60 typedef int8_t KeyboardID;
61 typedef int8_t MouseID;
62 typedef int8_t JoystickID;
63 typedef int8_t MouseButtonID;
64 typedef int8_t JoystickHatID;
65 
66 static const KeyboardID ALL_KEYBOARDS = -1;
67 static const MouseID ALL_MICE = -1;
68 static const JoystickID ALL_JOYSTICKS = -1;
69 
70 enum MouseAxis {
71  MOUSE_AXIS_INVALID = -1,
72  MOUSE_AXIS_0,
73  MOUSE_AXIS_1,
74  MOUSE_AXIS_2,
75  MOUSE_AXIS_3,
76  MOUSE_AXIS_MAX,
77  MOUSE_AXIS_X = MOUSE_AXIS_0,
78  MOUSE_AXIS_Y = MOUSE_AXIS_1
79 };
80 
81 enum JoystickAxis {
82  JOYSTICK_AXIS_INVALID = -1,
83  JOYSTICK_AXIS_0,
84  JOYSTICK_AXIS_1,
85  JOYSTICK_AXIS_2,
86  JOYSTICK_AXIS_3,
87  JOYSTICK_AXIS_4,
88  JOYSTICK_AXIS_5,
89  JOYSTICK_AXIS_6,
90  JOYSTICK_AXIS_7,
91  JOYSTICK_AXIS_MAX,
92  JOYSTICK_AXIS_X = JOYSTICK_AXIS_0,
93  JOYSTICK_AXIS_Y = JOYSTICK_AXIS_1,
94  JOYSTICK_AXIS_XL = JOYSTICK_AXIS_0,
95  JOYSTICK_AXIS_YL = JOYSTICK_AXIS_1,
96  JOYSTICK_AXIS_XR = JOYSTICK_AXIS_2,
97  JOYSTICK_AXIS_YR = JOYSTICK_AXIS_3,
98  JOYSTICK_AXIS_LTRIGGER = JOYSTICK_AXIS_4,
99  JOYSTICK_AXIS_RTRIGGER = JOYSTICK_AXIS_5,
100 };
101 
102 enum JoystickHatAxis {
103  JOYSTICK_HAT_AXIS_X,
104  JOYSTICK_HAT_AXIS_Y
105 };
106 
107 /* All IDs here (aside INVALID) match up with those
108  * that SDL uses. This is for convenience */
109 enum JoystickButton : int8_t {
110  JOYSTICK_BUTTON_INVALID = -1,
111  JOYSTICK_BUTTON_A,
112  JOYSTICK_BUTTON_B,
113  JOYSTICK_BUTTON_X,
114  JOYSTICK_BUTTON_Y,
115  JOYSTICK_BUTTON_BACK,
116  JOYSTICK_BUTTON_GUIDE,
117  JOYSTICK_BUTTON_START,
118  JOYSTICK_BUTTON_LEFT_STICK,
119  JOYSTICK_BUTTON_RIGHT_STICK,
120  JOYSTICK_BUTTON_LEFT_SHOULDER,
121  JOYSTICK_BUTTON_RIGHT_SHOULDER,
122  JOYSTICK_BUTTON_DPAD_UP,
123  JOYSTICK_BUTTON_DPAD_DOWN,
124  JOYSTICK_BUTTON_DPAD_LEFT,
125  JOYSTICK_BUTTON_DPAD_RIGHT,
126  JOYSTICK_BUTTON_DPAD2_UP,
127  JOYSTICK_BUTTON_DPAD2_DOWN,
128  JOYSTICK_BUTTON_DPAD2_LEFT,
129  JOYSTICK_BUTTON_DPAD2_RIGHT,
130  JOYSTICK_BUTTON_MAX
131 };
132 
133 const static std::size_t MAX_MOUSE_BUTTONS = 16u;
134 const static std::size_t MAX_JOYSTICK_HATS = 4u;
135 const static std::size_t MAX_DEVICE_TYPE_COUNT = 4u;
136 
137 enum HatPosition {
138  HAT_POSITION_CENTERED = 0,
139  HAT_POSITION_UP = 1,
140  HAT_POSITION_RIGHT = 2,
141  HAT_POSITION_DOWN = 4,
142  HAT_POSITION_LEFT = 8,
143  HAT_POSITION_RIGHT_UP = HAT_POSITION_RIGHT | HAT_POSITION_UP,
144  HAT_POSITION_RIGHT_DOWN = HAT_POSITION_RIGHT | HAT_POSITION_DOWN,
145  HAT_POSITION_LEFT_UP = HAT_POSITION_LEFT | HAT_POSITION_UP,
146  HAT_POSITION_LEFT_DOWN = HAT_POSITION_LEFT | HAT_POSITION_DOWN
147 };
148 
150  public RefCounted<InputState> {
151 
152 public:
153  void pre_update(float dt);
154  void update(float dt);
155 
156  /* These methods should be called by BaseWindow subclasses when the OS sends the corresponding
157  * event. You should not call these unless you are implementing support for a new platform!
158  */
159 
160  void _update_mouse_devices(const std::vector<MouseDeviceInfo>& device_info) {
161  mouse_count_ = std::min(device_info.size(), MAX_DEVICE_TYPE_COUNT);
162  for(decltype(mouse_count_) i = 0; i < mouse_count_; ++i) {
163  mice_[i].button_count = device_info[i].button_count;
164  mice_[i].axis_count = device_info[i].axis_count;
165  }
166  }
167 
168  void _update_keyboard_devices(const std::vector<KeyboardDeviceInfo>& device_info) {
169  keyboard_count_ = std::min(device_info.size(), MAX_DEVICE_TYPE_COUNT);
170  }
171 
172  void _update_joystick_devices(const std::vector<JoystickDeviceInfo>& device_info);
173 
174  void _handle_key_down(KeyboardID keyboard_id, KeyboardCode code);
175  void _handle_key_up(KeyboardID keyboard_id, KeyboardCode code);
176 
177  void _handle_mouse_motion(MouseID mouse_id, uint32_t x, uint32_t y, int32_t xrel, int32_t yrel);
178  void _handle_mouse_down(MouseID mouse_id, MouseButtonID button_id);
179  void _handle_mouse_up(MouseID mouse_id, MouseButtonID button_id);
180 
181  // value must be a value between -1.0f and 1.0f!
182  void _handle_joystick_axis_motion(JoystickID joypad_id, JoystickAxis axis, float value);
183 
184  void _handle_joystick_button_down(JoystickID joypad_id, JoystickButton button);
185  void _handle_joystick_button_up(JoystickID joypad_id, JoystickButton button);
186  void _handle_joystick_hat_motion(JoystickID joypad_id, JoystickHatID hat_id, HatPosition position);
187 
188  // Public state accessor functions
189  bool keyboard_key_state(KeyboardID keyboard_id, KeyboardCode code) const;
190 
191  bool mouse_button_state(MouseID mouse_id, MouseButtonID button) const;
192 
193  float mouse_axis_state(MouseID mouse_id, MouseAxis axis) const;
194  Vec2 mouse_position(MouseID mouse_id) const;
195 
196  bool joystick_button_state(JoystickID joystick_id, JoystickButton button) const;
197  float joystick_axis_state(JoystickID joystick_id, JoystickAxis axis) const;
198  HatPosition joystick_hat_state(JoystickID joystick_id, JoystickHatID hat) const;
199 
200  std::size_t joystick_count() const { return joystick_count_; }
201  std::size_t keyboard_count() const { return keyboard_count_; }
202  std::size_t mouse_count() const { return mouse_count_; }
203 
204  JoystickAxis linked_axis(JoystickID id, JoystickAxis axis);
205 private:
206  struct KeyboardState {
207  bool keys[MAX_KEYBOARD_CODES] = {0};
208  };
209 
210  uint8_t keyboard_count_ = 0;
211  KeyboardState keyboards_[4];
212 
213  struct MouseState {
214  uint8_t button_count = 0;
215  uint8_t axis_count = 0;
216 
217  bool buttons[MAX_MOUSE_BUTTONS] = {0};
218  float axises[MOUSE_AXIS_MAX] = {0};
219 
220  uint32_t x = 0;
221  uint32_t y = 0;
222  };
223 
224  uint8_t mouse_count_ = 0;
225  MouseState mice_[4];
226 
227  struct JoystickState {
228  uint8_t button_count = 0;
229  uint8_t axis_count = 0;
230  uint8_t hat_count = 0;
231 
232  bool buttons[JOYSTICK_BUTTON_MAX] = {0};
233  float axises[JOYSTICK_AXIS_MAX] = {0};
234  HatPosition hats[MAX_JOYSTICK_HATS] = {HAT_POSITION_CENTERED};
235  };
236 
237  uint8_t joystick_count_ = 0;
238  JoystickState joysticks_[4];
239 };
240 
241 }
242 #endif // INPUT_CONTROLLER_H
smlt::KeyboardDeviceInfo
Definition: input_state.h:49
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::MouseDeviceInfo
Definition: input_state.h:53
smlt::InputState
Definition: input_state.h:150
smlt::Vec2
Definition: vec2.h:13
smlt::JoystickDeviceInfo
Definition: input_state.h:41