Merge pull request #56239 from madmiraal/fix-44178-3.x

[3.x] Simplify InputDefault::joy_axis code by using float instead of struct JoyAxis
This commit is contained in:
Rémi Verschelde 2022-01-14 20:00:09 +01:00 committed by GitHub
commit d23f2b7450
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 73 additions and 141 deletions

View File

@ -805,47 +805,32 @@ void InputDefault::joy_button(int p_device, int p_button, bool p_pressed) {
// no event? // no event?
} }
void InputDefault::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { void InputDefault::joy_axis(int p_device, int p_axis, float p_value) {
_THREAD_SAFE_METHOD_; _THREAD_SAFE_METHOD_;
ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX); ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
Joypad &joy = joy_names[p_device]; Joypad &joy = joy_names[p_device];
if (joy.last_axis[p_axis] == p_value.value) { if (joy.last_axis[p_axis] == p_value) {
return; return;
} }
//when changing direction quickly, insert fake event to release pending inputmap actions joy.last_axis[p_axis] = p_value;
float last = joy.last_axis[p_axis];
if (p_value.min == 0 && (last < 0.25 || last > 0.75) && (last - 0.5) * (p_value.value - 0.5) < 0) {
JoyAxis jx;
jx.min = p_value.min;
jx.value = p_value.value < 0.5 ? 0.6 : 0.4;
joy_axis(p_device, p_axis, jx);
} else if (ABS(last) > 0.5 && last * p_value.value <= 0) {
JoyAxis jx;
jx.min = p_value.min;
jx.value = last > 0 ? 0.1 : -0.1;
joy_axis(p_device, p_axis, jx);
}
joy.last_axis[p_axis] = p_value.value;
float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value;
if (joy.mapping == -1) { if (joy.mapping == -1) {
_axis_event(p_device, p_axis, val); _axis_event(p_device, p_axis, p_value);
return; return;
}; };
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, val); JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value);
if (map.type == TYPE_BUTTON) { if (map.type == TYPE_BUTTON) {
//send axis event for triggers // Send axis event for triggers
if (map.index == JOY_L2 || map.index == JOY_R2) { if (map.index == JOY_L2 || map.index == JOY_R2) {
float value = p_value.min == 0 ? p_value.value : 0.5f + p_value.value / 2.0f; // Convert to a value between 0.0f and 1.0f.
int axis = map.index == JOY_L2 ? JOY_ANALOG_L2 : JOY_ANALOG_R2; float value = 0.5f + p_value / 2.0f;
_axis_event(p_device, axis, value); _axis_event(p_device, map.index, value);
} }
bool pressed = map.value > 0.5; bool pressed = map.value > 0.5;
@ -885,10 +870,9 @@ void InputDefault::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
} }
if (map.type == TYPE_AXIS) { if (map.type == TYPE_AXIS) {
_axis_event(p_device, map.index, val); _axis_event(p_device, map.index, p_value);
return; return;
} }
//printf("invalid mapping\n");
} }
void InputDefault::joy_hat(int p_device, int p_val) { void InputDefault::joy_hat(int p_device, int p_val) {

View File

@ -132,11 +132,6 @@ public:
JOYPADS_MAX = 16, JOYPADS_MAX = 16,
}; };
struct JoyAxis {
int min;
float value;
};
private: private:
enum JoyType { enum JoyType {
TYPE_BUTTON, TYPE_BUTTON,
@ -284,7 +279,7 @@ public:
void parse_mapping(String p_mapping); void parse_mapping(String p_mapping);
void joy_button(int p_device, int p_button, bool p_pressed); void joy_button(int p_device, int p_button, bool p_pressed);
void joy_axis(int p_device, int p_axis, const JoyAxis &p_value); void joy_axis(int p_device, int p_axis, float p_value);
void joy_hat(int p_device, int p_val); void joy_hat(int p_device, int p_val);
virtual void add_joy_mapping(String p_mapping, bool p_update_existing = false); virtual void add_joy_mapping(String p_mapping, bool p_update_existing = false);

View File

@ -409,10 +409,12 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p
if (tracker.is_valid()) { if (tracker.is_valid()) {
int joyid = tracker->get_joy_id(); int joyid = tracker->get_joy_id();
if (joyid != -1) { if (joyid != -1) {
InputDefault::JoyAxis jx; float value = p_value;
jx.min = p_can_be_negative ? -1 : 0; if (!p_can_be_negative) {
jx.value = p_value; // Convert to a value between -1.0f and 1.0f.
input->joy_axis(joyid, p_axis, jx); value = p_value * 2.0f - 1.0f;
}
input->joy_axis(joyid, p_axis, value);
} }
} }
} }

View File

@ -415,10 +415,8 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
int *axes = godot_webxr_get_controller_axes(p_controller_id); int *axes = godot_webxr_get_controller_axes(p_controller_id);
if (axes) { if (axes) {
for (int i = 0; i < axes[0]; i++) { for (int i = 0; i < axes[0]; i++) {
InputDefault::JoyAxis joy_axis; float value = *((float *)axes + (i + 1));
joy_axis.min = -1; input->joy_axis(p_controller_id + 100, i, value);
joy_axis.value = *((float *)axes + (i + 1));
input->joy_axis(p_controller_id + 100, i, joy_axis);
} }
free(axes); free(axes);
} }

View File

@ -40,10 +40,7 @@ void AndroidInputHandler::process_joy_event(const JoypadEvent &p_event) {
input->joy_button(p_event.device, p_event.index, p_event.pressed); input->joy_button(p_event.device, p_event.index, p_event.pressed);
break; break;
case JOY_EVENT_AXIS: case JOY_EVENT_AXIS:
InputDefault::JoyAxis value; input->joy_axis(p_event.device, p_event.index, p_event.value);
value.min = -1;
value.value = p_event.value;
input->joy_axis(p_event.device, p_event.index, value);
break; break;
case JOY_EVENT_HAT: case JOY_EVENT_HAT:
input->joy_hat(p_event.device, p_event.hat); input->joy_hat(p_event.device, p_event.hat);

View File

@ -292,24 +292,22 @@ void JoypadIPhone::start_processing() {
gamepad.dpad.right.isPressed); gamepad.dpad.right.isPressed);
}; };
InputDefault::JoyAxis jx;
jx.min = -1;
if (element == gamepad.leftThumbstick) { if (element == gamepad.leftThumbstick) {
jx.value = gamepad.leftThumbstick.xAxis.value; float value = gamepad.leftThumbstick.xAxis.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, value);
jx.value = -gamepad.leftThumbstick.yAxis.value; value = -gamepad.leftThumbstick.yAxis.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, value);
} else if (element == gamepad.rightThumbstick) { } else if (element == gamepad.rightThumbstick) {
jx.value = gamepad.rightThumbstick.xAxis.value; float value = gamepad.rightThumbstick.xAxis.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, value);
jx.value = -gamepad.rightThumbstick.yAxis.value; value = -gamepad.rightThumbstick.yAxis.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, value);
} else if (element == gamepad.leftTrigger) { } else if (element == gamepad.leftTrigger) {
jx.value = gamepad.leftTrigger.value; float value = gamepad.leftTrigger.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, value);
} else if (element == gamepad.rightTrigger) { } else if (element == gamepad.rightTrigger) {
jx.value = gamepad.rightTrigger.value; float value = gamepad.rightTrigger.value;
OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx); OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, value);
} }
}; };
} else if (controller.microGamepad != nil) { } else if (controller.microGamepad != nil) {

View File

@ -149,7 +149,7 @@ public:
int get_unused_joy_id(); int get_unused_joy_id();
void joy_connection_changed(int p_idx, bool p_connected, String p_name); void joy_connection_changed(int p_idx, bool p_connected, String p_name);
void joy_button(int p_device, int p_button, bool p_pressed); void joy_button(int p_device, int p_button, bool p_pressed);
void joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value); void joy_axis(int p_device, int p_axis, float p_value);
virtual void set_mouse_show(bool p_show); virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab); virtual void set_mouse_grab(bool p_grab);

View File

@ -307,7 +307,7 @@ void OSIPhone::joy_button(int p_device, int p_button, bool p_pressed) {
input->joy_button(p_device, p_button, p_pressed); input->joy_button(p_device, p_button, p_pressed);
}; };
void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value) { void OSIPhone::joy_axis(int p_device, int p_axis, float p_value) {
input->joy_axis(p_device, p_axis, p_value); input->joy_axis(p_device, p_axis, p_value);
}; };

View File

@ -597,24 +597,16 @@ void OS_JavaScript::process_joypads() {
continue; continue;
} }
for (int b = 0; b < s_btns_num; b++) { for (int b = 0; b < s_btns_num; b++) {
float value = s_btns[b];
// Buttons 6 and 7 in the standard mapping need to be // Buttons 6 and 7 in the standard mapping need to be
// axis to be handled as JOY_ANALOG by Godot. // axis to be handled as JOY_ANALOG by Godot.
if (s_standard && (b == 6 || b == 7)) { if (s_standard && (b == 6 || b == 7)) {
InputDefault::JoyAxis joy_axis; input->joy_axis(idx, b, s_btns[b]);
joy_axis.min = 0;
joy_axis.value = value;
int a = b == 6 ? JOY_ANALOG_L2 : JOY_ANALOG_R2;
input->joy_axis(idx, a, joy_axis);
} else { } else {
input->joy_button(idx, b, value); input->joy_button(idx, b, s_btns[b]);
} }
} }
for (int a = 0; a < s_axes_num; a++) { for (int a = 0; a < s_axes_num; a++) {
InputDefault::JoyAxis joy_axis; input->joy_axis(idx, a, s_axes[a]);
joy_axis.min = -1;
joy_axis.value = s_axes[a];
input->joy_axis(idx, a, joy_axis);
} }
} }
} }

View File

@ -456,20 +456,9 @@ void JoypadOSX::poll_joypads() const {
} }
} }
static const InputDefault::JoyAxis axis_correct(int p_value, int p_min, int p_max) { static float axis_correct(int p_value, int p_min, int p_max) {
InputDefault::JoyAxis jx; // Convert to a value between -1.0f and 1.0f.
if (p_min < 0) { return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f;
jx.min = -1;
if (p_value < 0) {
jx.value = (float)-p_value / p_min;
} else
jx.value = (float)p_value / p_max;
}
if (p_min == 0) {
jx.min = 0;
jx.value = 0.0f + (float)p_value / p_max;
}
return jx;
} }
void JoypadOSX::process_joypads() { void JoypadOSX::process_joypads() {

View File

@ -134,13 +134,12 @@ void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Inp
input->joy_connection_changed(idx, false, "Xbox Controller"); input->joy_connection_changed(idx, false, "Xbox Controller");
} }
InputDefault::JoyAxis JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const { float JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
InputDefault::JoyAxis jx; if (p_trigger) {
// Convert to a value between -1.0f and 1.0f.
jx.min = p_trigger ? 0 : -1; return 2.0f * p_val - 1.0f;
jx.value = (float)(p_negate ? -p_val : p_val); }
return (float)(p_negate ? -p_val : p_val);
return jx;
} }
void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) { void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) {

View File

@ -82,7 +82,7 @@ private:
void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value); void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value); void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
InputDefault::JoyAxis axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const; float axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const;
void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop(int p_device, uint64_t p_timestamp); void joypad_vibration_stop(int p_device, uint64_t p_timestamp);
}; };

View File

@ -447,33 +447,27 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
input->joy_hat(p_device, dpad_val); input->joy_hat(p_device, dpad_val);
}; };
InputDefault::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { float JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
InputDefault::JoyAxis jx;
if (Math::abs(p_val) < MIN_JOY_AXIS) { if (Math::abs(p_val) < MIN_JOY_AXIS) {
jx.min = p_trigger ? 0 : -1; return p_trigger ? -1.0f : 0.0f;
jx.value = 0.0f;
return jx;
} }
if (p_xinput) { if (!p_xinput) {
if (p_trigger) { return (float)p_val / MAX_JOY_AXIS;
jx.min = 0;
jx.value = (float)p_val / MAX_TRIGGER;
return jx;
}
jx.min = -1;
if (p_val < 0) {
jx.value = (float)p_val / MAX_JOY_AXIS;
} else {
jx.value = (float)p_val / (MAX_JOY_AXIS - 1);
}
if (p_negate) {
jx.value = -jx.value;
}
return jx;
} }
jx.min = -1; if (p_trigger) {
jx.value = (float)p_val / MAX_JOY_AXIS; // Convert to a value between -1.0f and 1.0f.
return jx; return 2.0f * p_val / MAX_TRIGGER - 1.0f;
}
float value;
if (p_val < 0) {
value = (float)p_val / MAX_JOY_AXIS;
} else {
value = (float)p_val / (MAX_JOY_AXIS - 1);
}
if (p_negate) {
value = -value;
}
return value;
} }
void JoypadWindows::joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) { void JoypadWindows::joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) {

View File

@ -140,7 +140,7 @@ private:
void joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop_xinput(int p_device, uint64_t p_timestamp); void joypad_vibration_stop_xinput(int p_device, uint64_t p_timestamp);
InputDefault::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; float axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const;
XInputGetState_t xinput_get_state; XInputGetState_t xinput_get_state;
XInputSetState_t xinput_set_state; XInputSetState_t xinput_set_state;
}; };

View File

@ -70,13 +70,9 @@ JoypadLinux::Joypad::~Joypad() {
void JoypadLinux::Joypad::reset() { void JoypadLinux::Joypad::reset() {
dpad = 0; dpad = 0;
fd = -1; fd = -1;
InputDefault::JoyAxis jx;
jx.min = -1;
jx.value = 0.0f;
for (int i = 0; i < MAX_ABS; i++) { for (int i = 0; i < MAX_ABS; i++) {
abs_map[i] = -1; abs_map[i] = -1;
curr_axis[i] = jx; curr_axis[i] = 0;
} }
} }
@ -441,23 +437,11 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
joy.ff_effect_timestamp = p_timestamp; joy.ff_effect_timestamp = p_timestamp;
} }
InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const { float JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
int min = p_abs->minimum; int min = p_abs->minimum;
int max = p_abs->maximum; int max = p_abs->maximum;
InputDefault::JoyAxis jx; // Convert to a value between -1.0f and 1.0f.
return 2.0f * (p_value - min) / (max - min) - 1.0f;
if (min < 0) {
jx.min = -1;
if (p_value < 0) {
jx.value = (float)-p_value / min;
} else {
jx.value = (float)p_value / max;
}
} else if (min == 0) {
jx.min = 0;
jx.value = 0.0f + (float)p_value / max;
}
return jx;
} }
void JoypadLinux::process_joypads() { void JoypadLinux::process_joypads() {
@ -526,7 +510,7 @@ void JoypadLinux::process_joypads() {
return; return;
} }
if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) { if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
InputDefault::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value); float value = axis_correct(joy->abs_info[ev.code], ev.value);
joy->curr_axis[joy->abs_map[ev.code]] = value; joy->curr_axis[joy->abs_map[ev.code]] = value;
} }
break; break;

View File

@ -53,7 +53,7 @@ private:
}; };
struct Joypad { struct Joypad {
InputDefault::JoyAxis curr_axis[MAX_ABS]; float curr_axis[MAX_ABS];
int key_map[MAX_KEY]; int key_map[MAX_KEY];
int abs_map[MAX_ABS]; int abs_map[MAX_ABS];
int dpad; int dpad;
@ -98,7 +98,7 @@ private:
void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop(int p_id, uint64_t p_timestamp); void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
InputDefault::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const; float axis_correct(const input_absinfo *p_abs, int p_value) const;
}; };
#endif #endif