diff options
Diffstat (limited to 'core/input/input.cpp')
-rw-r--r-- | core/input/input.cpp | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp index 4a32abfafa..f3f5940118 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -285,7 +285,7 @@ bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const { 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)); - return action_state.has(p_action) && action_state[p_action].pressed && (p_exact ? action_state[p_action].exact : true); + return action_state.has(p_action) && action_state[p_action].pressed > 0 && (p_exact ? action_state[p_action].exact : true); } bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const { @@ -475,7 +475,8 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S } joy_names[p_idx] = js; - emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected); + // Ensure this signal is emitted on the main thread, as some platforms (e.g. Linux) call this from a different thread. + call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected); } Vector3 Input::get_gravity() const { @@ -696,23 +697,50 @@ 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)) { + bool is_joypad_axis = jm.is_valid(); + bool is_pressed = false; + if (!p_event->is_echo()) { 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(); + bool is_joypad_axis_valid_zone_enter = false; + if (is_joypad_axis) { + if (!action.axis_pressed) { + is_joypad_axis_valid_zone_enter = true; + action.pressed++; + action.axis_pressed = true; + } + } else { + action.pressed++; + } + if (action.pressed == 1 && (is_joypad_axis_valid_zone_enter || !is_joypad_axis)) { + action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); + } + is_pressed = true; } else { - action.pressed = false; - action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); - action.released_process_frame = Engine::get_singleton()->get_process_frames(); + bool is_released = true; + if (is_joypad_axis) { + if (action.axis_pressed) { + action.axis_pressed = false; + } else { + is_released = false; + } + } + + if (is_released) { + if (action.pressed == 1) { + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); + } + action.pressed = MAX(action.pressed - 1, 0); + } } - action.strength = 0.0f; - action.raw_strength = 0.0f; action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true); } - action.strength = p_event->get_action_strength(E.key); - action.raw_strength = p_event->get_action_raw_strength(E.key); + + if (is_pressed || action.pressed == 0) { + action.strength = p_event->get_action_strength(E.key); + action.raw_strength = p_event->get_action_raw_strength(E.key); + } } } @@ -830,9 +858,11 @@ void Input::action_press(const StringName &p_action, float p_strength) { // Create or retrieve existing action. Action &action = action_state[p_action]; - action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); - action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); - action.pressed = true; + action.pressed++; + if (action.pressed == 1) { + action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); + } action.strength = p_strength; action.raw_strength = p_strength; action.exact = true; @@ -842,9 +872,11 @@ void Input::action_release(const StringName &p_action) { // Create or retrieve existing action. Action &action = action_state[p_action]; - action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); - action.released_process_frame = Engine::get_singleton()->get_process_frames(); - action.pressed = false; + action.pressed--; + if (action.pressed == 0) { + 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 = true; @@ -1005,8 +1037,10 @@ void Input::release_pressed_events() { joy_buttons_pressed.clear(); _joy_axis.clear(); - for (const KeyValue<StringName, Input::Action> &E : action_state) { - if (E.value.pressed) { + for (KeyValue<StringName, Input::Action> &E : action_state) { + if (E.value.pressed > 0) { + // Make sure the action is really released. + E.value.pressed = 1; action_release(E.key); } } |