diff options
Diffstat (limited to 'core/input/input.cpp')
-rw-r--r-- | core/input/input.cpp | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp index 1348389481..d481acf005 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -113,6 +113,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis); ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name); ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid); + ClassDB::bind_method(D_METHOD("should_ignore_device", "vendor_id", "product_id"), &Input::should_ignore_device); ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads); ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength); ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration); @@ -297,10 +298,13 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con return false; } + // Backward compatibility for legacy behavior, only return true if currently pressed. + bool pressed_requirement = legacy_just_pressed_behavior ? E->value.pressed : true; + if (Engine::get_singleton()->is_in_physics_frame()) { - return E->value.pressed && E->value.physics_frame == Engine::get_singleton()->get_physics_frames(); + return pressed_requirement && E->value.pressed_physics_frame == Engine::get_singleton()->get_physics_frames(); } else { - return E->value.pressed && E->value.process_frame == Engine::get_singleton()->get_process_frames(); + return pressed_requirement && E->value.pressed_process_frame == Engine::get_singleton()->get_process_frames(); } } @@ -315,10 +319,13 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co return false; } + // Backward compatibility for legacy behavior, only return true if currently released. + bool released_requirement = legacy_just_pressed_behavior ? !E->value.pressed : true; + if (Engine::get_singleton()->is_in_physics_frame()) { - return !E->value.pressed && E->value.physics_frame == Engine::get_singleton()->get_physics_frames(); + return released_requirement && E->value.released_physics_frame == Engine::get_singleton()->get_physics_frames(); } else { - return !E->value.pressed && E->value.process_frame == Engine::get_singleton()->get_process_frames(); + return released_requirement && E->value.released_process_frame == Engine::get_singleton()->get_process_frames(); } } @@ -686,19 +693,24 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em for (const KeyValue<StringName, InputMap::Action> &E : InputMap::get_singleton()->get_action_map()) { if (InputMap::get_singleton()->event_is_action(p_event, E.key)) { + Action &action = action_state[E.key]; // If not echo and action pressed state has changed if (!p_event->is_echo() && is_action_pressed(E.key, false) != p_event->is_action_pressed(E.key)) { - Action action; - action.physics_frame = Engine::get_singleton()->get_physics_frames(); - action.process_frame = Engine::get_singleton()->get_process_frames(); - action.pressed = p_event->is_action_pressed(E.key); + if (p_event->is_action_pressed(E.key)) { + action.pressed = true; + action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); + } else { + action.pressed = false; + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); + } action.strength = 0.0f; action.raw_strength = 0.0f; action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true); - action_state[E.key] = action; } - action_state[E.key].strength = p_event->get_action_strength(E.key); - action_state[E.key].raw_strength = p_event->get_action_raw_strength(E.key); + action.strength = p_event->get_action_strength(E.key); + action.raw_strength = p_event->get_action_raw_strength(E.key); } } @@ -813,29 +825,27 @@ Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, con } void Input::action_press(const StringName &p_action, float p_strength) { - Action action; + // Create or retrieve existing action. + Action &action = action_state[p_action]; - action.physics_frame = Engine::get_singleton()->get_physics_frames(); - action.process_frame = Engine::get_singleton()->get_process_frames(); + action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); action.pressed = true; action.strength = p_strength; action.raw_strength = p_strength; action.exact = true; - - action_state[p_action] = action; } void Input::action_release(const StringName &p_action) { - Action action; + // Create or retrieve existing action. + Action &action = action_state[p_action]; - action.physics_frame = Engine::get_singleton()->get_physics_frames(); - action.process_frame = Engine::get_singleton()->get_process_frames(); + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); action.pressed = false; - action.strength = 0.f; - action.raw_strength = 0.f; + action.strength = 0.0f; + action.raw_strength = 0.0f; action.exact = true; - - action_state[p_action] = action; } void Input::set_emulate_touch_from_mouse(bool p_emulate) { @@ -1356,8 +1366,9 @@ void Input::parse_mapping(String p_mapping) { String output = entry[idx].get_slice(":", 0).replace(" ", ""); String input = entry[idx].get_slice(":", 1).replace(" ", ""); - ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2, - vformat("Invalid device mapping entry \"%s\" in mapping:\n%s", entry[idx], p_mapping)); + if (output.length() < 1 || input.length() < 2) { + continue; + } if (output == "platform" || output == "hint") { continue; @@ -1488,6 +1499,11 @@ String Input::get_joy_guid(int p_device) const { return joy_names[p_device].uid; } +bool Input::should_ignore_device(int p_vendor_id, int p_product_id) const { + uint32_t full_id = (((uint32_t)p_vendor_id) << 16) | ((uint16_t)p_product_id); + return ignored_device_ids.has(full_id); +} + TypedArray<int> Input::get_connected_joypads() { TypedArray<int> ret; HashMap<int, Joypad>::Iterator elem = joy_names.begin(); @@ -1531,6 +1547,33 @@ Input::Input() { parse_mapping(entries[i]); } } + + String env_ignore_devices = OS::get_singleton()->get_environment("SDL_GAMECONTROLLER_IGNORE_DEVICES"); + if (!env_ignore_devices.is_empty()) { + Vector<String> entries = env_ignore_devices.split(","); + for (int i = 0; i < entries.size(); i++) { + Vector<String> vid_pid = entries[i].split("/"); + + if (vid_pid.size() < 2) { + continue; + } + + print_verbose(vformat("Device Ignored -- Vendor: %s Product: %s", vid_pid[0], vid_pid[1])); + const uint16_t vid_unswapped = vid_pid[0].hex_to_int(); + const uint16_t pid_unswapped = vid_pid[1].hex_to_int(); + const uint16_t vid = BSWAP16(vid_unswapped); + const uint16_t pid = BSWAP16(pid_unswapped); + + uint32_t full_id = (((uint32_t)vid) << 16) | ((uint16_t)pid); + ignored_device_ids.insert(full_id); + } + } + + legacy_just_pressed_behavior = GLOBAL_DEF("input_devices/compatibility/legacy_just_pressed_behavior", false); + if (Engine::get_singleton()->is_editor_hint()) { + // Always use standard behavior in the editor. + legacy_just_pressed_behavior = false; + } } Input::~Input() { |