feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@ __XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,guide:b10,back
Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
# Web
standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Web,
standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:+a4,righttrigger:+a5,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Web,
Linux24c6581a,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,
Linux0e6f0301,Logic 3 Controller (xbox compatible),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,
Linux045e028e,Microsoft X-Box 360 pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,

View file

@ -77,6 +77,10 @@ Input *Input::singleton = nullptr;
void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr;
void (*Input::set_mouse_mode_override_func)(Input::MouseMode) = nullptr;
Input::MouseMode (*Input::get_mouse_mode_override_func)() = nullptr;
void (*Input::set_mouse_mode_override_enabled_func)(bool) = nullptr;
bool (*Input::is_mouse_mode_override_enabled_func)() = nullptr;
void (*Input::warp_mouse_func)(const Vector2 &p_position) = nullptr;
Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
void (*Input::set_custom_mouse_cursor_func)(const Ref<Resource> &, Input::CursorShape, const Vector2 &) = nullptr;
@ -86,7 +90,7 @@ Input *Input::get_singleton() {
}
void Input::set_mouse_mode(MouseMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 5);
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
set_mouse_mode_func(p_mode);
}
@ -94,6 +98,23 @@ Input::MouseMode Input::get_mouse_mode() const {
return get_mouse_mode_func();
}
void Input::set_mouse_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
set_mouse_mode_override_func(p_mode);
}
Input::MouseMode Input::get_mouse_mode_override() const {
return get_mouse_mode_override_func();
}
void Input::set_mouse_mode_override_enabled(bool p_override_enabled) {
set_mouse_mode_override_enabled_func(p_override_enabled);
}
bool Input::is_mouse_mode_override_enabled() {
return is_mouse_mode_override_enabled_func();
}
void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_anything_pressed"), &Input::is_anything_pressed);
ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
@ -160,6 +181,7 @@ void Input::_bind_methods() {
BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN);
BIND_ENUM_CONSTANT(MOUSE_MODE_MAX);
BIND_ENUM_CONSTANT(CURSOR_ARROW);
BIND_ENUM_CONSTANT(CURSOR_IBEAM);
@ -197,7 +219,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
continue;
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
r_options->push_back(name.quote());
}
}
@ -252,6 +274,10 @@ Input::VelocityTrack::VelocityTrack() {
bool Input::is_anything_pressed() const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
if (!keys_pressed.is_empty() || !joy_buttons_pressed.is_empty() || !mouse_button_mask.is_empty()) {
return true;
}
@ -265,23 +291,63 @@ bool Input::is_anything_pressed() const {
return false;
}
bool Input::is_anything_pressed_except_mouse() const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
if (!keys_pressed.is_empty() || !joy_buttons_pressed.is_empty()) {
return true;
}
for (const KeyValue<StringName, Input::ActionState> &E : action_states) {
if (E.value.cache.pressed) {
return true;
}
}
return false;
}
bool Input::is_key_pressed(Key p_keycode) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
return keys_pressed.has(p_keycode);
}
bool Input::is_physical_key_pressed(Key p_keycode) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
return physical_keys_pressed.has(p_keycode);
}
bool Input::is_key_label_pressed(Key p_keycode) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
return key_label_pressed.has(p_keycode);
}
bool Input::is_mouse_button_pressed(MouseButton p_button) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
return mouse_button_mask.has_flag(mouse_button_to_mask(p_button));
}
@ -295,11 +361,21 @@ static JoyButton _combine_device(JoyButton p_value, int p_device) {
bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return false;
}
return joy_buttons_pressed.has(_combine_device(p_button, p_device));
}
bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const {
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
if (disable_input) {
return false;
}
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
if (!E) {
return false;
@ -310,6 +386,11 @@ bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const {
bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const {
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
if (disable_input) {
return false;
}
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
if (!E) {
return false;
@ -331,6 +412,11 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con
bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const {
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
if (disable_input) {
return false;
}
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
if (!E) {
return false;
@ -352,6 +438,11 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co
float Input::get_action_strength(const StringName &p_action, bool p_exact) const {
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
if (disable_input) {
return 0.0f;
}
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
if (!E) {
return 0.0f;
@ -366,6 +457,11 @@ float Input::get_action_strength(const StringName &p_action, bool p_exact) const
float Input::get_action_raw_strength(const StringName &p_action, bool p_exact) const {
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
if (disable_input) {
return 0.0f;
}
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
if (!E) {
return 0.0f;
@ -410,6 +506,11 @@ Vector2 Input::get_vector(const StringName &p_negative_x, const StringName &p_po
float Input::get_joy_axis(int p_device, JoyAxis p_axis) const {
_THREAD_SAFE_METHOD_
if (disable_input) {
return 0;
}
JoyAxis c = _combine_device(p_axis, p_device);
if (_joy_axis.has(c)) {
return _joy_axis[c];
@ -491,10 +592,9 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
for (int i = 0; i < map_db.size(); i++) {
if (js.uid == map_db[i].uid) {
mapping = i;
js.name = map_db[i].name;
}
}
js.mapping = mapping;
_set_joypad_mapping(js, mapping);
} else {
js.connected = false;
for (int i = 0; i < (int)JoyButton::MAX; i++) {
@ -513,21 +613,49 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
Vector3 Input::get_gravity() const {
_THREAD_SAFE_METHOD_
#ifdef DEBUG_ENABLED
if (!gravity_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_gravity` is not enabled in project settings.");
}
#endif
return gravity;
}
Vector3 Input::get_accelerometer() const {
_THREAD_SAFE_METHOD_
#ifdef DEBUG_ENABLED
if (!accelerometer_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_accelerometer` is not enabled in project settings.");
}
#endif
return accelerometer;
}
Vector3 Input::get_magnetometer() const {
_THREAD_SAFE_METHOD_
#ifdef DEBUG_ENABLED
if (!magnetometer_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_magnetometer` is not enabled in project settings.");
}
#endif
return magnetometer;
}
Vector3 Input::get_gyroscope() const {
_THREAD_SAFE_METHOD_
#ifdef DEBUG_ENABLED
if (!gyroscope_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_gyroscope` is not enabled in project settings.");
}
#endif
return gyroscope;
}
@ -662,6 +790,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
button_event->set_canceled(st->is_canceled());
button_event->set_button_index(MouseButton::LEFT);
button_event->set_double_click(st->is_double_tap());
button_event->set_window_id(st->get_window_id());
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
if (st->is_pressed()) {
@ -699,6 +828,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
motion_event->set_velocity(sd->get_velocity());
motion_event->set_screen_velocity(sd->get_screen_velocity());
motion_event->set_button_mask(mouse_button_mask);
motion_event->set_window_id(sd->get_window_id());
_parse_input_event_impl(motion_event, true);
}
@ -906,7 +1036,7 @@ void Input::action_release(const StringName &p_action) {
// Create or retrieve existing action.
ActionState &action_state = action_states[p_action];
action_state.cache.pressed = 0;
action_state.cache.pressed = false;
action_state.cache.strength = 0.0;
action_state.cache.raw_strength = 0.0;
// As input may come in part way through a physics tick, the earliest we can react to it is the next physics tick.
@ -1455,9 +1585,6 @@ void Input::parse_mapping(const String &p_mapping) {
return;
}
CharString uid;
uid.resize(17);
mapping.uid = entry[0];
mapping.name = entry[1];
@ -1558,26 +1685,94 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
for (KeyValue<int, Joypad> &E : joy_names) {
Joypad &joy = E.value;
if (joy.uid == uid) {
joy.mapping = map_db.size() - 1;
_set_joypad_mapping(joy, map_db.size() - 1);
}
}
}
}
void Input::remove_joy_mapping(const String &p_guid) {
// One GUID can exist multiple times in `map_db`, and
// `add_joy_mapping` can choose not to update the existing mapping,
// so the indices can be all over the place. Therefore we need to remember them.
Vector<int> removed_idx;
int min_removed_idx = -1;
int max_removed_idx = -1;
int fallback_mapping_offset = 0;
for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
map_db.remove_at(i);
if (max_removed_idx == -1) {
max_removed_idx = i;
}
min_removed_idx = i;
removed_idx.push_back(i);
if (i < fallback_mapping) {
fallback_mapping_offset++;
} else if (i == fallback_mapping) {
fallback_mapping = -1;
WARN_PRINT_ONCE(vformat("Removed fallback joypad input mapping \"%s\". This could lead to joypads not working as intended.", p_guid));
}
}
}
if (min_removed_idx == -1) {
return; // Nothing removed.
}
if (fallback_mapping > 0) {
// Fix the shifted index.
fallback_mapping -= fallback_mapping_offset;
}
int removed_idx_size = removed_idx.size();
// Update joypad mapping references: some
// * should use the fallback_mapping (if set; if not, they get unmapped), or
// * need their mapping reference fixed, because the deletion(s) offset them.
for (KeyValue<int, Joypad> &E : joy_names) {
Joypad &joy = E.value;
if (joy.uid == p_guid) {
joy.mapping = -1;
if (joy.mapping < min_removed_idx) {
continue; // Not affected.
}
if (joy.mapping > max_removed_idx) {
_set_joypad_mapping(joy, joy.mapping - removed_idx_size);
continue; // Simple offset fix.
}
// removed_idx is in reverse order (ie. high to low), because the first loop is in reverse order.
for (int i = 0; i < removed_idx.size(); i++) {
if (removed_idx[i] == joy.mapping) {
// Set to fallback_mapping, if defined, else unmap the joypad.
// Currently, the fallback_mapping is only set internally, and only for Android.
_set_joypad_mapping(joy, fallback_mapping);
break;
}
if (removed_idx[i] < joy.mapping) {
// Complex offset fix:
// This mapping was shifted by `(removed_idx_size - i)` deletions.
_set_joypad_mapping(joy, joy.mapping - (removed_idx_size - i));
break;
}
}
}
}
void Input::_set_joypad_mapping(Joypad &p_js, int p_map_index) {
if (p_map_index != fallback_mapping && p_map_index >= 0 && p_map_index < map_db.size() && p_js.uid != "__XINPUT_DEVICE__") {
// Prefer the joypad name defined in the mapping.
// Exceptions:
// * On Windows for XInput devices the mapping would change the joypad's name to a collective name.
// * A fallback mapping is not allowed to override the joypad's name.
p_js.name = map_db[p_map_index].name;
}
p_js.mapping = p_map_index;
}
void Input::set_fallback_mapping(const String &p_guid) {
for (int i = 0; i < map_db.size(); i++) {
if (map_db[i].uid == p_guid) {
@ -1634,6 +1829,14 @@ int Input::get_unused_joy_id() {
return -1;
}
void Input::set_disable_input(bool p_disable) {
disable_input = p_disable;
}
bool Input::is_input_disabled() const {
return disable_input;
}
Input::Input() {
singleton = this;
@ -1683,6 +1886,11 @@ Input::Input() {
// Always use standard behavior in the editor.
legacy_just_pressed_behavior = false;
}
accelerometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_accelerometer", false);
gravity_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gravity", false);
gyroscope_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gyroscope", false);
magnetometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_magnetometer", false);
}
Input::~Input() {

View file

@ -47,12 +47,14 @@ class Input : public Object {
static constexpr uint64_t MAX_EVENT = 32;
public:
// Keep synced with "DisplayServer::MouseMode" enum.
enum MouseMode {
MOUSE_MODE_VISIBLE,
MOUSE_MODE_HIDDEN,
MOUSE_MODE_CAPTURED,
MOUSE_MODE_CONFINED,
MOUSE_MODE_CONFINED_HIDDEN,
MOUSE_MODE_MAX,
};
#undef CursorShape
@ -92,13 +94,18 @@ private:
RBSet<JoyButton> joy_buttons_pressed;
RBMap<JoyAxis, float> _joy_axis;
//RBMap<StringName,int> custom_action_press;
bool gravity_enabled = false;
Vector3 gravity;
bool accelerometer_enabled = false;
Vector3 accelerometer;
bool magnetometer_enabled = false;
Vector3 magnetometer;
bool gyroscope_enabled = false;
Vector3 gyroscope;
Vector2 mouse_pos;
int64_t mouse_window = 0;
bool legacy_just_pressed_behavior = false;
bool disable_input = false;
struct ActionState {
uint64_t pressed_physics_frame = UINT64_MAX;
@ -175,7 +182,7 @@ private:
HashSet<uint32_t> ignored_device_ids;
int fallback_mapping = -1;
int fallback_mapping = -1; // Index of the guid in map_db.
CursorShape default_shape = CURSOR_ARROW;
@ -236,6 +243,8 @@ private:
Vector<JoyDeviceMapping> map_db;
void _set_joypad_mapping(Joypad &p_js, int p_map_index);
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button);
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value, JoyAxisRange &r_range);
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]);
@ -257,6 +266,10 @@ private:
static void (*set_mouse_mode_func)(MouseMode);
static MouseMode (*get_mouse_mode_func)();
static void (*set_mouse_mode_override_func)(MouseMode);
static MouseMode (*get_mouse_mode_override_func)();
static void (*set_mouse_mode_override_enabled_func)(bool);
static bool (*is_mouse_mode_override_enabled_func)();
static void (*warp_mouse_func)(const Vector2 &p_position);
static CursorShape (*get_current_cursor_shape_func)();
@ -275,6 +288,10 @@ protected:
public:
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
void set_mouse_mode_override(MouseMode p_mode);
MouseMode get_mouse_mode_override() const;
void set_mouse_mode_override_enabled(bool p_override_enabled);
bool is_mouse_mode_override_enabled();
#ifdef TOOLS_ENABLED
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
@ -283,6 +300,7 @@ public:
static Input *get_singleton();
bool is_anything_pressed() const;
bool is_anything_pressed_except_mouse() const;
bool is_key_pressed(Key p_keycode) const;
bool is_physical_key_pressed(Key p_keycode) const;
bool is_key_label_pressed(Key p_keycode) const;
@ -376,6 +394,9 @@ public:
void set_event_dispatch_function(EventDispatchFunc p_function);
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
Input();
~Input();
};

View file

@ -33,7 +33,7 @@ def make_default_controller_mappings(target, source, env):
guid = line_parts[0]
if guid in platform_mappings[current_platform]:
g.write(
"// WARNING - DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format(
"// WARNING: DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format(
src_path, current_platform, platform_mappings[current_platform][guid]
)
)

View file

@ -31,6 +31,8 @@
#ifndef INPUT_ENUMS_H
#define INPUT_ENUMS_H
#include "core/error/error_macros.h"
enum class HatDir {
UP = 0,
RIGHT = 1,
@ -131,6 +133,8 @@ enum class MouseButtonMask {
};
inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
ERR_FAIL_COND_V(button == MouseButton::NONE, MouseButtonMask::NONE);
return MouseButtonMask(1 << ((int)button - 1));
}

View file

@ -754,6 +754,8 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
mb->set_factor(factor);
mb->set_button_index(button_index);
mb->merge_meta_from(this);
return mb;
}
@ -974,6 +976,8 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
mm->set_velocity(p_xform.basis_xform(get_velocity()));
mm->set_screen_velocity(get_screen_velocity());
mm->merge_meta_from(this);
return mm;
}
@ -1088,7 +1092,7 @@ void InputEventMouseMotion::_bind_methods() {
///////////////////////////////////
void InputEventJoypadMotion::set_axis(JoyAxis p_axis) {
ERR_FAIL_COND(p_axis < JoyAxis::LEFT_X || p_axis > JoyAxis::MAX);
ERR_FAIL_COND(p_axis < JoyAxis::INVALID || p_axis > JoyAxis::MAX);
axis = p_axis;
emit_changed();
@ -1100,7 +1104,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const {
void InputEventJoypadMotion::set_axis_value(float p_value) {
axis_value = p_value;
pressed = Math::abs(axis_value) >= 0.5f;
pressed = Math::abs(axis_value) >= InputMap::DEFAULT_DEADZONE;
emit_changed();
}
@ -1366,6 +1370,8 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co
st->set_canceled(canceled);
st->set_double_tap(double_tap);
st->merge_meta_from(this);
return st;
}
@ -1494,6 +1500,8 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con
sd->set_velocity(p_xform.basis_xform(velocity));
sd->set_screen_velocity(get_screen_velocity());
sd->merge_meta_from(this);
return sd;
}
@ -1705,6 +1713,8 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform,
ev->set_position(p_xform.xform(get_position() + p_local_ofs));
ev->set_factor(get_factor());
ev->merge_meta_from(this);
return ev;
}
@ -1745,6 +1755,8 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con
ev->set_position(p_xform.xform(get_position() + p_local_ofs));
ev->set_delta(get_delta());
ev->merge_meta_from(this);
return ev;
}

View file

@ -0,0 +1,41 @@
/**************************************************************************/
/* input_map.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
void InputMap::_add_action_bind_compat_97281(const StringName &p_action, float p_deadzone) {
add_action(p_action, p_deadzone);
}
void InputMap::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::_add_action_bind_compat_97281, DEFVAL(0.5f));
}
#endif // DISABLE_DEPRECATED

View file

@ -29,6 +29,7 @@
/**************************************************************************/
#include "input_map.h"
#include "input_map.compat.inc"
#include "core/config/project_settings.h"
#include "core/input/input.h"
@ -43,7 +44,7 @@ int InputMap::ALL_DEVICES = -1;
void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f));
ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(DEFAULT_DEADZONE));
ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action);
ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone);
@ -105,7 +106,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis
continue;
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
r_options->push_back(name.quote());
}
}
@ -115,7 +116,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis
#endif
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\".");
ERR_FAIL_COND_MSG(input_map.has(p_action), vformat("InputMap already has action \"%s\".", String(p_action)));
input_map[p_action] = Action();
static int last_id = 1;
input_map[p_action].id = last_id;
@ -157,7 +158,7 @@ List<StringName> InputMap::get_actions() const {
}
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength, int *r_event_index) const {
ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
ERR_FAIL_COND_V(p_event.is_null(), nullptr);
int i = 0;
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
@ -253,8 +254,8 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
int InputMap::event_get_index(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const {
int index = -1;
event_get_action_status(p_event, p_action, p_exact_match, nullptr, nullptr, nullptr, &index);
return index;
bool valid = event_get_action_status(p_event, p_action, p_exact_match, nullptr, nullptr, nullptr, &index);
return valid ? index : -1;
}
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength, int *r_event_index) const {
@ -303,10 +304,10 @@ void InputMap::load_from_project_settings() {
continue;
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length());
Dictionary action = GLOBAL_GET(pi.name);
float deadzone = action.has("deadzone") ? (float)action["deadzone"] : 0.5f;
float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE;
Array events = action["events"];
add_action(name, deadzone);
@ -400,6 +401,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = {
{ "ui_filedialog_refresh", TTRC("Refresh") },
{ "ui_filedialog_show_hidden", TTRC("Show Hidden") },
{ "ui_swap_input_direction ", TTRC("Swap Input Direction") },
{ "ui_unicode_start", TTRC("Start Unicode Character Input") },
{ "", ""}
/* clang-format on */
};
@ -517,12 +519,15 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
default_builtin_cache.insert("ui_text_completion_query", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::ENTER));
inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
inputs.push_back(InputEventKey::create_reference(KeyModifierMask::SHIFT | Key::TAB));
inputs.push_back(InputEventKey::create_reference(KeyModifierMask::SHIFT | Key::ENTER));
inputs.push_back(InputEventKey::create_reference(KeyModifierMask::SHIFT | Key::KP_ENTER));
default_builtin_cache.insert("ui_text_completion_accept", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::TAB));
inputs.push_back(InputEventKey::create_reference(Key::ENTER));
inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
default_builtin_cache.insert("ui_text_completion_replace", inputs);
// Newlines
@ -532,7 +537,6 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
default_builtin_cache.insert("ui_text_newline", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::ENTER | KeyModifierMask::CMD_OR_CTRL));
inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER | KeyModifierMask::CMD_OR_CTRL));
default_builtin_cache.insert("ui_text_newline_blank", inputs);
@ -754,6 +758,10 @@ const HashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
default_builtin_cache.insert("ui_text_submit", inputs);
inputs = List<Ref<InputEvent>>();
inputs.push_back(InputEventKey::create_reference(Key::U | KeyModifierMask::CTRL | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_unicode_start", inputs);
// ///// UI Graph Shortcuts /////
inputs = List<Ref<InputEvent>>();

View file

@ -54,6 +54,8 @@ public:
List<Ref<InputEvent>> inputs;
};
static constexpr float DEFAULT_DEADZONE = 0.2f;
private:
static InputMap *singleton;
@ -69,12 +71,17 @@ private:
protected:
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
void _add_action_bind_compat_97281(const StringName &p_action, float p_deadzone = 0.5);
static void _bind_compatibility_methods();
#endif // DISABLE_DEPRECATED
public:
static _FORCE_INLINE_ InputMap *get_singleton() { return singleton; }
bool has_action(const StringName &p_action) const;
List<StringName> get_actions() const;
void add_action(const StringName &p_action, float p_deadzone = 0.5);
void add_action(const StringName &p_action, float p_deadzone = DEFAULT_DEADZONE);
void erase_action(const StringName &p_action);
float action_get_deadzone(const StringName &p_action);

View file

@ -29,7 +29,6 @@
/**************************************************************************/
#include "shortcut.h"
#include "core/os/keyboard.h"
void Shortcut::set_events(const Array &p_events) {
for (int i = 0; i < p_events.size(); i++) {