summaryrefslogtreecommitdiffstats
path: root/core/input/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/input/input.cpp')
-rw-r--r--core/input/input.cpp128
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: