Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/input/input.h
9903 views
1
/**************************************************************************/
2
/* input.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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
31
#pragma once
32
33
#include "core/input/input_event.h"
34
#include "core/object/object.h"
35
#include "core/os/keyboard.h"
36
#include "core/os/thread_safe.h"
37
#include "core/templates/rb_set.h"
38
#include "core/variant/typed_array.h"
39
40
class Input : public Object {
41
GDCLASS(Input, Object);
42
_THREAD_SAFE_CLASS_
43
44
static inline Input *singleton = nullptr;
45
46
static constexpr uint64_t MAX_EVENT = 32;
47
48
public:
49
// Keep synced with "DisplayServer::MouseMode" enum.
50
enum MouseMode {
51
MOUSE_MODE_VISIBLE,
52
MOUSE_MODE_HIDDEN,
53
MOUSE_MODE_CAPTURED,
54
MOUSE_MODE_CONFINED,
55
MOUSE_MODE_CONFINED_HIDDEN,
56
MOUSE_MODE_MAX,
57
};
58
59
#undef CursorShape
60
enum CursorShape {
61
CURSOR_ARROW,
62
CURSOR_IBEAM,
63
CURSOR_POINTING_HAND,
64
CURSOR_CROSS,
65
CURSOR_WAIT,
66
CURSOR_BUSY,
67
CURSOR_DRAG,
68
CURSOR_CAN_DROP,
69
CURSOR_FORBIDDEN,
70
CURSOR_VSIZE,
71
CURSOR_HSIZE,
72
CURSOR_BDIAGSIZE,
73
CURSOR_FDIAGSIZE,
74
CURSOR_MOVE,
75
CURSOR_VSPLIT,
76
CURSOR_HSPLIT,
77
CURSOR_HELP,
78
CURSOR_MAX
79
};
80
81
static constexpr int32_t JOYPADS_MAX = 16;
82
83
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
84
85
private:
86
BitField<MouseButtonMask> mouse_button_mask = MouseButtonMask::NONE;
87
88
RBSet<Key> key_label_pressed;
89
RBSet<Key> physical_keys_pressed;
90
RBSet<Key> keys_pressed;
91
RBSet<JoyButton> joy_buttons_pressed;
92
RBMap<JoyAxis, float> _joy_axis;
93
//RBMap<StringName,int> custom_action_press;
94
bool gravity_enabled = false;
95
Vector3 gravity;
96
bool accelerometer_enabled = false;
97
Vector3 accelerometer;
98
bool magnetometer_enabled = false;
99
Vector3 magnetometer;
100
bool gyroscope_enabled = false;
101
Vector3 gyroscope;
102
Vector2 mouse_pos;
103
int64_t mouse_window = 0;
104
bool legacy_just_pressed_behavior = false;
105
bool disable_input = false;
106
107
struct ActionState {
108
uint64_t pressed_physics_frame = UINT64_MAX;
109
uint64_t pressed_process_frame = UINT64_MAX;
110
uint64_t released_physics_frame = UINT64_MAX;
111
uint64_t released_process_frame = UINT64_MAX;
112
ObjectID pressed_event_id;
113
ObjectID released_event_id;
114
bool exact = true;
115
116
struct DeviceState {
117
bool pressed[MAX_EVENT] = { false };
118
float strength[MAX_EVENT] = { 0.0 };
119
float raw_strength[MAX_EVENT] = { 0.0 };
120
};
121
bool api_pressed = false;
122
float api_strength = 0.0;
123
HashMap<int, DeviceState> device_states;
124
125
// Cache.
126
struct ActionStateCache {
127
bool pressed = false;
128
float strength = false;
129
float raw_strength = false;
130
} cache;
131
};
132
133
HashMap<StringName, ActionState> action_states;
134
135
bool emulate_touch_from_mouse = false;
136
bool emulate_mouse_from_touch = false;
137
bool agile_input_event_flushing = false;
138
bool use_accumulated_input = true;
139
140
int mouse_from_touch_index = -1;
141
142
struct VibrationInfo {
143
float weak_magnitude;
144
float strong_magnitude;
145
float duration; // Duration in seconds
146
uint64_t timestamp;
147
};
148
149
HashMap<int, VibrationInfo> joy_vibration;
150
151
struct VelocityTrack {
152
uint64_t last_tick = 0;
153
Vector2 velocity;
154
Vector2 screen_velocity;
155
Vector2 accum;
156
Vector2 screen_accum;
157
float accum_t = 0.0f;
158
float min_ref_frame;
159
float max_ref_frame;
160
161
void update(const Vector2 &p_delta_p, const Vector2 &p_screen_delta_p);
162
void reset();
163
VelocityTrack();
164
};
165
166
struct Joypad {
167
StringName name;
168
StringName uid;
169
bool connected = false;
170
bool last_buttons[(size_t)JoyButton::MAX] = { false };
171
float last_axis[(size_t)JoyAxis::MAX] = { 0.0f };
172
HatMask last_hat = HatMask::CENTER;
173
int mapping = -1;
174
int hat_current = 0;
175
Dictionary info;
176
};
177
178
VelocityTrack mouse_velocity_track;
179
HashMap<int, VelocityTrack> touch_velocity_track;
180
HashMap<int, Joypad> joy_names;
181
182
HashSet<uint32_t> ignored_device_ids;
183
184
int fallback_mapping = -1; // Index of the guid in map_db.
185
186
CursorShape default_shape = CURSOR_ARROW;
187
188
enum JoyType {
189
TYPE_BUTTON,
190
TYPE_AXIS,
191
TYPE_HAT,
192
TYPE_MAX,
193
};
194
195
enum JoyAxisRange {
196
NEGATIVE_HALF_AXIS = -1,
197
FULL_AXIS = 0,
198
POSITIVE_HALF_AXIS = 1
199
};
200
201
struct JoyEvent {
202
int type = TYPE_MAX;
203
int index = -1; // Can be either JoyAxis or JoyButton.
204
float value = 0.f;
205
};
206
207
struct JoyBinding {
208
JoyType inputType;
209
union {
210
JoyButton button;
211
212
struct {
213
JoyAxis axis;
214
JoyAxisRange range;
215
bool invert;
216
} axis;
217
218
struct {
219
HatDir hat;
220
HatMask hat_mask;
221
} hat;
222
223
} input;
224
225
JoyType outputType;
226
union {
227
JoyButton button;
228
229
struct {
230
JoyAxis axis;
231
JoyAxisRange range;
232
} axis;
233
234
} output;
235
};
236
237
struct JoyDeviceMapping {
238
String uid;
239
String name;
240
Vector<JoyBinding> bindings;
241
};
242
243
Vector<JoyDeviceMapping> map_db;
244
245
void _set_joypad_mapping(Joypad &p_js, int p_map_index);
246
247
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button);
248
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value, JoyAxisRange &r_range);
249
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]);
250
JoyButton _get_output_button(const String &output);
251
JoyAxis _get_output_axis(const String &output);
252
void _button_event(int p_device, JoyButton p_index, bool p_pressed);
253
void _axis_event(int p_device, JoyAxis p_axis, float p_value);
254
void _update_action_cache(const StringName &p_action_name, ActionState &r_action_state);
255
256
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
257
258
List<Ref<InputEvent>> buffered_events;
259
#ifdef DEBUG_ENABLED
260
HashSet<Ref<InputEvent>> frame_parsed_events;
261
uint64_t last_parsed_frame = UINT64_MAX;
262
#endif
263
264
friend class DisplayServer;
265
266
static void (*set_mouse_mode_func)(MouseMode);
267
static MouseMode (*get_mouse_mode_func)();
268
static void (*set_mouse_mode_override_func)(MouseMode);
269
static MouseMode (*get_mouse_mode_override_func)();
270
static void (*set_mouse_mode_override_enabled_func)(bool);
271
static bool (*is_mouse_mode_override_enabled_func)();
272
static void (*warp_mouse_func)(const Vector2 &p_position);
273
274
static CursorShape (*get_current_cursor_shape_func)();
275
static void (*set_custom_mouse_cursor_func)(const Ref<Resource> &, CursorShape, const Vector2 &);
276
277
EventDispatchFunc event_dispatch_function = nullptr;
278
279
#ifndef DISABLE_DEPRECATED
280
void _vibrate_handheld_bind_compat_91143(int p_duration_ms = 500);
281
static void _bind_compatibility_methods();
282
#endif // DISABLE_DEPRECATED
283
284
protected:
285
static void _bind_methods();
286
287
public:
288
void set_mouse_mode(MouseMode p_mode);
289
MouseMode get_mouse_mode() const;
290
void set_mouse_mode_override(MouseMode p_mode);
291
MouseMode get_mouse_mode_override() const;
292
void set_mouse_mode_override_enabled(bool p_override_enabled);
293
bool is_mouse_mode_override_enabled();
294
295
#ifdef TOOLS_ENABLED
296
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
297
#endif
298
299
static Input *get_singleton();
300
301
bool is_anything_pressed() const;
302
bool is_anything_pressed_except_mouse() const;
303
bool is_key_pressed(Key p_keycode) const;
304
bool is_physical_key_pressed(Key p_keycode) const;
305
bool is_key_label_pressed(Key p_keycode) const;
306
bool is_mouse_button_pressed(MouseButton p_button) const;
307
bool is_joy_button_pressed(int p_device, JoyButton p_button) const;
308
bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
309
bool is_action_just_pressed(const StringName &p_action, bool p_exact = false) const;
310
bool is_action_just_released(const StringName &p_action, bool p_exact = false) const;
311
bool is_action_just_pressed_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
312
bool is_action_just_released_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
313
float get_action_strength(const StringName &p_action, bool p_exact = false) const;
314
float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const;
315
316
float get_axis(const StringName &p_negative_action, const StringName &p_positive_action) const;
317
Vector2 get_vector(const StringName &p_negative_x, const StringName &p_positive_x, const StringName &p_negative_y, const StringName &p_positive_y, float p_deadzone = -1.0f) const;
318
319
float get_joy_axis(int p_device, JoyAxis p_axis) const;
320
String get_joy_name(int p_idx);
321
TypedArray<int> get_connected_joypads();
322
Vector2 get_joy_vibration_strength(int p_device);
323
float get_joy_vibration_duration(int p_device);
324
uint64_t get_joy_vibration_timestamp(int p_device);
325
void joy_connection_changed(int p_idx, bool p_connected, const String &p_name, const String &p_guid = "", const Dictionary &p_joypad_info = Dictionary());
326
327
Vector3 get_gravity() const;
328
Vector3 get_accelerometer() const;
329
Vector3 get_magnetometer() const;
330
Vector3 get_gyroscope() const;
331
332
Point2 get_mouse_position() const;
333
Vector2 get_last_mouse_velocity();
334
Vector2 get_last_mouse_screen_velocity();
335
BitField<MouseButtonMask> get_mouse_button_mask() const;
336
337
void warp_mouse(const Vector2 &p_position);
338
Point2 warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
339
340
void parse_input_event(const Ref<InputEvent> &p_event);
341
342
void set_gravity(const Vector3 &p_gravity);
343
void set_accelerometer(const Vector3 &p_accel);
344
void set_magnetometer(const Vector3 &p_magnetometer);
345
void set_gyroscope(const Vector3 &p_gyroscope);
346
void set_joy_axis(int p_device, JoyAxis p_axis, float p_value);
347
348
void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
349
void stop_joy_vibration(int p_device);
350
void vibrate_handheld(int p_duration_ms = 500, float p_amplitude = -1.0);
351
352
void set_mouse_position(const Point2 &p_posf);
353
354
void action_press(const StringName &p_action, float p_strength = 1.f);
355
void action_release(const StringName &p_action);
356
357
void set_emulate_touch_from_mouse(bool p_emulate);
358
bool is_emulating_touch_from_mouse() const;
359
void ensure_touch_mouse_raised();
360
361
void set_emulate_mouse_from_touch(bool p_emulate);
362
bool is_emulating_mouse_from_touch() const;
363
364
CursorShape get_default_cursor_shape() const;
365
void set_default_cursor_shape(CursorShape p_shape);
366
CursorShape get_current_cursor_shape() const;
367
void set_custom_mouse_cursor(const Ref<Resource> &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
368
369
void parse_mapping(const String &p_mapping);
370
void joy_button(int p_device, JoyButton p_button, bool p_pressed);
371
void joy_axis(int p_device, JoyAxis p_axis, float p_value);
372
void joy_hat(int p_device, BitField<HatMask> p_val);
373
374
void add_joy_mapping(const String &p_mapping, bool p_update_existing = false);
375
void remove_joy_mapping(const String &p_guid);
376
377
int get_unused_joy_id();
378
379
bool is_joy_known(int p_device);
380
String get_joy_guid(int p_device) const;
381
bool should_ignore_device(int p_vendor_id, int p_product_id) const;
382
Dictionary get_joy_info(int p_device) const;
383
void set_fallback_mapping(const String &p_guid);
384
385
#ifdef DEBUG_ENABLED
386
void flush_frame_parsed_events();
387
#endif
388
void flush_buffered_events();
389
bool is_agile_input_event_flushing();
390
void set_agile_input_event_flushing(bool p_enable);
391
void set_use_accumulated_input(bool p_enable);
392
bool is_using_accumulated_input();
393
394
void release_pressed_events();
395
396
void set_event_dispatch_function(EventDispatchFunc p_function);
397
398
void set_disable_input(bool p_disable);
399
bool is_input_disabled() const;
400
401
Input();
402
~Input();
403
};
404
405
VARIANT_ENUM_CAST(Input::MouseMode);
406
VARIANT_ENUM_CAST(Input::CursorShape);
407
408