1 /*************************************************************************/
2 /*  input_default.h                                                      */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #ifndef INPUT_DEFAULT_H
31 #define INPUT_DEFAULT_H
32 
33 #include "os/input.h"
34 
35 class InputDefault : public Input {
36 
37 	OBJ_TYPE(InputDefault, Input);
38 	_THREAD_SAFE_CLASS_
39 
40 	int mouse_button_mask;
41 	Set<int> keys_pressed;
42 	Set<int> joy_buttons_pressed;
43 	Map<int, float> _joy_axis;
44 	Map<StringName, int> custom_action_press;
45 	Vector3 gravity;
46 	Vector3 accelerometer;
47 	Vector3 magnetometer;
48 	Vector3 gyroscope;
49 	Vector2 mouse_pos;
50 	MainLoop *main_loop;
51 
52 	bool emulate_touch;
53 
54 	struct VibrationInfo {
55 		float weak_magnitude;
56 		float strong_magnitude;
57 		float duration; // Duration in seconds
58 		uint64_t timestamp;
59 	};
60 
61 	Map<int, VibrationInfo> joy_vibration;
62 
63 	struct SpeedTrack {
64 
65 		uint64_t last_tick;
66 		Vector2 speed;
67 		Vector2 accum;
68 		float accum_t;
69 		float min_ref_frame;
70 		float max_ref_frame;
71 
72 		void update(const Vector2 &p_delta_p);
73 		void reset();
74 		SpeedTrack();
75 	};
76 
77 	struct Joystick {
78 		StringName name;
79 		StringName uid;
80 		bool connected;
81 		bool last_buttons[JOY_BUTTON_MAX + 19]; //apparently SDL specifies 35 possible buttons on android
82 		float last_axis[JOY_AXIS_MAX];
83 		float filter;
84 		int last_hat;
85 		int mapping;
86 		int hat_current;
87 
JoystickJoystick88 		Joystick() {
89 
90 			for (int i = 0; i < JOY_AXIS_MAX; i++) {
91 
92 				last_axis[i] = 0.0f;
93 			}
94 			for (int i = 0; i < JOY_BUTTON_MAX + 19; i++) {
95 
96 				last_buttons[i] = false;
97 			}
98 			connected = false;
99 			last_hat = HAT_MASK_CENTER;
100 			filter = 0.01f;
101 			mapping = -1;
102 		}
103 	};
104 
105 	SpeedTrack mouse_speed_track;
106 	Map<int, Joystick> joy_names;
107 	int fallback_mapping;
108 	RES custom_cursors[CURSOR_MAX] = { NULL };
109 
110 public:
111 	enum HatMask {
112 		HAT_MASK_CENTER = 0,
113 		HAT_MASK_UP = 1,
114 		HAT_MASK_RIGHT = 2,
115 		HAT_MASK_DOWN = 4,
116 		HAT_MASK_LEFT = 8,
117 	};
118 
119 	enum HatDir {
120 		HAT_UP,
121 		HAT_RIGHT,
122 		HAT_DOWN,
123 		HAT_LEFT,
124 		HAT_MAX,
125 	};
126 
127 	enum {
128 		JOYSTICKS_MAX = 16,
129 	};
130 
131 	struct JoyAxis {
132 		int min;
133 		float value;
134 	};
135 
136 private:
137 	enum JoyType {
138 		TYPE_BUTTON,
139 		TYPE_AXIS,
140 		TYPE_HAT,
141 		TYPE_MAX,
142 	};
143 
144 	struct JoyEvent {
145 		int type;
146 		int index;
147 		int value;
148 	};
149 
150 	struct JoyDeviceMapping {
151 
152 		String uid;
153 		String name;
154 		Map<int, JoyEvent> buttons;
155 		Map<int, JoyEvent> axis;
156 		JoyEvent hat[HAT_MAX];
157 	};
158 
159 	JoyEvent hat_map_default[HAT_MAX];
160 
161 	Vector<JoyDeviceMapping> map_db;
162 
163 	JoyEvent _find_to_event(String p_to);
164 	uint32_t _button_event(uint32_t p_last_id, int p_device, int p_index, bool p_pressed);
165 	uint32_t _axis_event(uint32_t p_last_id, int p_device, int p_axis, float p_value);
166 	float _handle_deadzone(int p_device, int p_axis, float p_value);
167 
168 public:
169 	virtual bool is_key_pressed(int p_scancode);
170 	virtual bool is_mouse_button_pressed(int p_button);
171 	virtual bool is_joy_button_pressed(int p_device, int p_button);
172 	virtual bool is_action_pressed(const StringName &p_action);
173 
174 	virtual float get_joy_axis(int p_device, int p_axis);
175 	String get_joy_name(int p_idx);
176 	virtual Array get_connected_joysticks();
177 	virtual Vector2 get_joy_vibration_strength(int p_device);
178 	virtual float get_joy_vibration_duration(int p_device);
179 	virtual uint64_t get_joy_vibration_timestamp(int p_device);
180 	void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid = "");
181 	void parse_joystick_mapping(String p_mapping, bool p_update_existing);
182 
183 	virtual Vector3 get_gravity();
184 	virtual Vector3 get_accelerometer();
185 	virtual Vector3 get_magnetometer();
186 	virtual Vector3 get_gyroscope();
187 
188 	virtual Point2 get_mouse_pos() const;
189 	virtual Point2 get_mouse_speed() const;
190 	virtual int get_mouse_button_mask() const;
191 
192 	virtual void warp_mouse_pos(const Vector2 &p_to);
193 	virtual Point2i warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect);
194 
195 	virtual void parse_input_event(const InputEvent &p_event);
196 
197 	void set_gravity(const Vector3 &p_gravity);
198 	void set_accelerometer(const Vector3 &p_accel);
199 	void set_magnetometer(const Vector3 &p_magnetometer);
200 	void set_gyroscope(const Vector3 &p_gyroscope);
201 	void set_joy_axis(int p_device, int p_axis, float p_value);
202 
203 	virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
204 	virtual void stop_joy_vibration(int p_device);
205 
206 	void set_main_loop(MainLoop *main_loop);
207 	void set_mouse_pos(const Point2 &p_posf);
208 
209 	void action_press(const StringName &p_action);
210 	void action_release(const StringName &p_action);
211 
212 	void iteration(float p_step);
213 
214 	void set_emulate_touch(bool p_emulate);
215 	virtual bool is_emulating_touchscreen() const;
216 
217 	virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
218 
219 	void parse_mapping(String p_mapping);
220 	uint32_t joy_button(uint32_t p_last_id, int p_device, int p_button, bool p_pressed);
221 	uint32_t joy_axis(uint32_t p_last_id, int p_device, int p_axis, const JoyAxis &p_value);
222 	uint32_t joy_hat(uint32_t p_last_id, int p_device, int p_val);
223 
224 	virtual void add_joy_mapping(String p_mapping, bool p_update_existing = false);
225 	virtual void remove_joy_mapping(String p_guid);
226 	virtual bool is_joy_known(int p_device);
227 	virtual String get_joy_guid(int p_device) const;
228 
229 	virtual String get_joy_button_string(int p_button);
230 	virtual String get_joy_axis_string(int p_axis);
231 	virtual int get_joy_axis_index_from_string(String p_axis);
232 	virtual int get_joy_button_index_from_string(String p_button);
233 
234 	int get_unused_joy_id();
235 
236 	bool is_joy_mapped(int p_device);
237 	String get_joy_guid_remapped(int p_device) const;
238 	void set_fallback_mapping(String p_guid);
239 	InputDefault();
240 };
241 
242 #endif // INPUT_DEFAULT_H
243