diff options
Diffstat (limited to 'core/input/input.cpp')
-rw-r--r-- | core/input/input.cpp | 128 |
1 files changed, 72 insertions, 56 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp index 19ea8c7317..257452b3d8 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -695,54 +695,34 @@ 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]; - bool is_pressed = false; - - if (!p_event->is_echo()) { - if (p_event->is_action_pressed(E.key)) { - if (jm.is_valid()) { - // If axis is already pressed, don't increase the pressed counter. - if (!action.axis_pressed) { - action.pressed++; - action.axis_pressed = true; - } - } else { - action.pressed++; - } - - is_pressed = true; - if (action.pressed == 1) { - action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); - action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); - } - } else { - bool is_released = true; - if (jm.is_valid()) { - // Same as above. Don't release axis when not pressed. - if (action.axis_pressed) { - action.axis_pressed = false; - } else { - is_released = false; - } - } + const int event_index = InputMap::get_singleton()->event_get_index(p_event, E.key); + if (event_index == -1) { + continue; + } - 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 &action = action_state[E.key]; + if (!p_event->is_echo()) { + if (p_event->is_action_pressed(E.key)) { + if (!action.pressed) { + action.pressed_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.pressed_process_frame = Engine::get_singleton()->get_process_frames(); } - action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true); - } + action.pressed |= ((uint64_t)1 << event_index); + } else { + action.pressed &= ~((uint64_t)1 << event_index); + action.pressed &= ~(1 << MAX_EVENT); // Always release the event from action_press() method. - 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); + if (!action.pressed) { + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); + } + _update_action_strength(action, MAX_EVENT, 0.0); + _update_action_raw_strength(action, MAX_EVENT, 0.0); } + action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key, true); } + _update_action_strength(action, event_index, p_event->get_action_strength(E.key)); + _update_action_raw_strength(action, event_index, p_event->get_action_raw_strength(E.key)); } if (event_dispatch_function) { @@ -859,13 +839,13 @@ void Input::action_press(const StringName &p_action, float p_strength) { // Create or retrieve existing action. Action &action = action_state[p_action]; - action.pressed++; - if (action.pressed == 1) { + if (!action.pressed) { 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.pressed |= 1 << MAX_EVENT; + _update_action_strength(action, MAX_EVENT, p_strength); + _update_action_raw_strength(action, MAX_EVENT, p_strength); action.exact = true; } @@ -873,13 +853,15 @@ void Input::action_release(const StringName &p_action) { // Create or retrieve existing action. Action &action = action_state[p_action]; - 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.pressed = 0; + action.strength = 0.0; + action.raw_strength = 0.0; + action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); + action.released_process_frame = Engine::get_singleton()->get_process_frames(); + for (uint64_t i = 0; i <= MAX_EVENT; i++) { + action.strengths[i] = 0.0; + action.raw_strengths[i] = 0.0; } - action.strength = 0.0f; - action.raw_strength = 0.0f; action.exact = true; } @@ -1096,7 +1078,8 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) { return; } - JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value); + JoyAxisRange range; + JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value, range); if (map.type == TYPE_BUTTON) { bool pressed = map.value > 0.5; @@ -1136,7 +1119,7 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) { if (map.type == TYPE_AXIS) { JoyAxis axis = JoyAxis(map.index); float value = map.value; - if (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT) { + if (range == FULL_AXIS && (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT)) { // Convert to a value between 0.0f and 1.0f. value = 0.5f + value / 2.0f; } @@ -1207,6 +1190,38 @@ void Input::_axis_event(int p_device, JoyAxis p_axis, float p_value) { parse_input_event(ievent); } +void Input::_update_action_strength(Action &p_action, int p_event_index, float p_strength) { + ERR_FAIL_INDEX(p_event_index, (int)MAX_EVENT + 1); + + float old_strength = p_action.strengths[p_event_index]; + p_action.strengths[p_event_index] = p_strength; + + if (p_strength > p_action.strength) { + p_action.strength = p_strength; + } else if (Math::is_equal_approx(old_strength, p_action.strength)) { + p_action.strength = p_strength; + for (uint64_t i = 0; i <= MAX_EVENT; i++) { + p_action.strength = MAX(p_action.strength, p_action.strengths[i]); + } + } +} + +void Input::_update_action_raw_strength(Action &p_action, int p_event_index, float p_strength) { + ERR_FAIL_INDEX(p_event_index, (int)MAX_EVENT + 1); + + float old_strength = p_action.raw_strengths[p_event_index]; + p_action.raw_strengths[p_event_index] = p_strength; + + if (p_strength > p_action.raw_strength) { + p_action.raw_strength = p_strength; + } else if (Math::is_equal_approx(old_strength, p_action.raw_strength)) { + p_action.raw_strength = p_strength; + for (uint64_t i = 0; i <= MAX_EVENT; i++) { + p_action.raw_strength = MAX(p_action.raw_strength, p_action.raw_strengths[i]); + } + } +} + Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button) { JoyEvent event; @@ -1242,7 +1257,7 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping, return event; } -Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value) { +Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value, JoyAxisRange &r_range) { JoyEvent event; for (int i = 0; i < mapping.bindings.size(); i++) { @@ -1288,6 +1303,7 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, J case TYPE_AXIS: event.index = (int)binding.output.axis.axis; event.value = value; + r_range = binding.output.axis.range; if (binding.output.axis.range != binding.input.axis.range) { switch (binding.output.axis.range) { case POSITIVE_HALF_AXIS: |