Browse Source

Merge pull request #56238 from madmiraal/fix-44178

Fix Actions mapped to triggers not using the full range
Rémi Verschelde 3 years ago
parent
commit
5f4e90d602

+ 12 - 22
core/input/input.cpp

@@ -916,40 +916,25 @@ void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) {
 	// no event?
 	// no event?
 }
 }
 
 
-void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) {
+void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) {
 	_THREAD_SAFE_METHOD_;
 	_THREAD_SAFE_METHOD_;
 
 
 	ERR_FAIL_INDEX((int)p_axis, (int)JoyAxis::MAX);
 	ERR_FAIL_INDEX((int)p_axis, (int)JoyAxis::MAX);
 
 
 	Joypad &joy = joy_names[p_device];
 	Joypad &joy = joy_names[p_device];
 
 
-	if (joy.last_axis[(size_t)p_axis] == p_value.value) {
+	if (joy.last_axis[(size_t)p_axis] == p_value) {
 		return;
 		return;
 	}
 	}
 
 
-	//when changing direction quickly, insert fake event to release pending inputmap actions
-	float last = joy.last_axis[(size_t)p_axis];
-	if (p_value.min == 0 && (last < 0.25 || last > 0.75) && (last - 0.5) * (p_value.value - 0.5) < 0) {
-		JoyAxisValue 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) {
-		JoyAxisValue jx;
-		jx.min = p_value.min;
-		jx.value = last > 0 ? 0.1 : -0.1;
-		joy_axis(p_device, p_axis, jx);
-	}
-
-	joy.last_axis[(size_t)p_axis] = p_value.value;
-	float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value;
+	joy.last_axis[(size_t)p_axis] = p_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) {
 		bool pressed = map.value > 0.5;
 		bool pressed = map.value > 0.5;
@@ -989,10 +974,15 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value)
 	}
 	}
 
 
 	if (map.type == TYPE_AXIS) {
 	if (map.type == TYPE_AXIS) {
-		_axis_event(p_device, (JoyAxis)map.index, map.value);
+		JoyAxis axis = JoyAxis(map.index);
+		float value = map.value;
+		if (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT) {
+			// Convert to a value between 0.0f and 1.0f.
+			value = 0.5f + value / 2.0f;
+		}
+		_axis_event(p_device, axis, value);
 		return;
 		return;
 	}
 	}
-	//printf("invalid mapping\n");
 }
 }
 
 
 void Input::joy_hat(int p_device, HatMask p_val) {
 void Input::joy_hat(int p_device, HatMask p_val) {

+ 1 - 6
core/input/input.h

@@ -77,11 +77,6 @@ public:
 		JOYPADS_MAX = 16,
 		JOYPADS_MAX = 16,
 	};
 	};
 
 
-	struct JoyAxisValue {
-		int min;
-		float value;
-	};
-
 	typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
 	typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
 
 
 private:
 private:
@@ -313,7 +308,7 @@ public:
 
 
 	void parse_mapping(String p_mapping);
 	void parse_mapping(String p_mapping);
 	void joy_button(int p_device, JoyButton p_button, bool p_pressed);
 	void joy_button(int p_device, JoyButton p_button, bool p_pressed);
-	void joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value);
+	void joy_axis(int p_device, JoyAxis p_axis, float p_value);
 	void joy_hat(int p_device, HatMask p_val);
 	void joy_hat(int p_device, HatMask p_val);
 
 
 	void add_joy_mapping(String p_mapping, bool p_update_existing = false);
 	void add_joy_mapping(String p_mapping, bool p_update_existing = false);

+ 1 - 4
platform/android/android_input_handler.cpp

@@ -39,10 +39,7 @@ void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_e
 			Input::get_singleton()->joy_button(p_event.device, (JoyButton)p_event.index, p_event.pressed);
 			Input::get_singleton()->joy_button(p_event.device, (JoyButton)p_event.index, p_event.pressed);
 			break;
 			break;
 		case JOY_EVENT_AXIS:
 		case JOY_EVENT_AXIS:
-			Input::JoyAxisValue value;
-			value.min = -1;
-			value.value = p_event.value;
-			Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, value);
+			Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, p_event.value);
 			break;
 			break;
 		case JOY_EVENT_HAT:
 		case JOY_EVENT_HAT:
 			Input::get_singleton()->joy_hat(p_event.device, p_event.hat);
 			Input::get_singleton()->joy_hat(p_event.device, p_event.hat);

+ 12 - 14
platform/iphone/joypad_iphone.mm

@@ -287,24 +287,22 @@ void JoypadIPhone::start_processing() {
 						gamepad.dpad.right.isPressed);
 						gamepad.dpad.right.isPressed);
 			};
 			};
 
 
-			Input::JoyAxisValue jx;
-			jx.min = -1;
 			if (element == gamepad.leftThumbstick) {
 			if (element == gamepad.leftThumbstick) {
-				jx.value = gamepad.leftThumbstick.xAxis.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, jx);
-				jx.value = -gamepad.leftThumbstick.yAxis.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, jx);
+				float value = gamepad.leftThumbstick.xAxis.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, value);
+				value = -gamepad.leftThumbstick.yAxis.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, value);
 			} else if (element == gamepad.rightThumbstick) {
 			} else if (element == gamepad.rightThumbstick) {
-				jx.value = gamepad.rightThumbstick.xAxis.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, jx);
-				jx.value = -gamepad.rightThumbstick.yAxis.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, jx);
+				float value = gamepad.rightThumbstick.xAxis.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, value);
+				value = -gamepad.rightThumbstick.yAxis.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, value);
 			} else if (element == gamepad.leftTrigger) {
 			} else if (element == gamepad.leftTrigger) {
-				jx.value = gamepad.leftTrigger.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, jx);
+				float value = gamepad.leftTrigger.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, value);
 			} else if (element == gamepad.rightTrigger) {
 			} else if (element == gamepad.rightTrigger) {
-				jx.value = gamepad.rightTrigger.value;
-				Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, jx);
+				float value = gamepad.rightTrigger.value;
+				Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, value);
 			};
 			};
 		};
 		};
 	} else if (controller.microGamepad != nil) {
 	} else if (controller.microGamepad != nil) {

+ 3 - 11
platform/javascript/display_server_javascript.cpp

@@ -558,24 +558,16 @@ void DisplayServerJavaScript::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 JoyAxis::TRIGGER by Godot.
 			// axis to be handled as JoyAxis::TRIGGER by Godot.
 			if (s_standard && (b == 6 || b == 7)) {
 			if (s_standard && (b == 6 || b == 7)) {
-				Input::JoyAxisValue joy_axis;
-				joy_axis.min = 0;
-				joy_axis.value = value;
-				JoyAxis a = b == 6 ? JoyAxis::TRIGGER_LEFT : JoyAxis::TRIGGER_RIGHT;
-				input->joy_axis(idx, a, joy_axis);
+				input->joy_axis(idx, (JoyAxis)b, s_btns[b]);
 			} else {
 			} else {
-				input->joy_button(idx, (JoyButton)b, value);
+				input->joy_button(idx, (JoyButton)b, s_btns[b]);
 			}
 			}
 		}
 		}
 		for (int a = 0; a < s_axes_num; a++) {
 		for (int a = 0; a < s_axes_num; a++) {
-			Input::JoyAxisValue joy_axis;
-			joy_axis.min = -1;
-			joy_axis.value = s_axes[a];
-			input->joy_axis(idx, (JoyAxis)a, joy_axis);
+			input->joy_axis(idx, (JoyAxis)a, s_axes[a]);
 		}
 		}
 	}
 	}
 }
 }

+ 5 - 21
platform/linuxbsd/joypad_linux.cpp

@@ -61,13 +61,9 @@ JoypadLinux::Joypad::~Joypad() {
 void JoypadLinux::Joypad::reset() {
 void JoypadLinux::Joypad::reset() {
 	dpad = HatMask::CENTER;
 	dpad = HatMask::CENTER;
 	fd = -1;
 	fd = -1;
-
-	Input::JoyAxisValue 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;
 	}
 	}
 }
 }
 
 
@@ -429,23 +425,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;
 }
 }
 
 
-Input::JoyAxisValue 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;
-	Input::JoyAxisValue jx;
-
-	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;
+	// Convert to a value between -1.0f and 1.0f.
+	return 2.0f * (p_value - min) / (max - min) - 1.0f;
 }
 }
 
 
 void JoypadLinux::process_joypads() {
 void JoypadLinux::process_joypads() {
@@ -514,7 +498,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]) {
-									Input::JoyAxisValue 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;

+ 2 - 2
platform/linuxbsd/joypad_linux.h

@@ -52,7 +52,7 @@ private:
 	};
 	};
 
 
 	struct Joypad {
 	struct Joypad {
-		Input::JoyAxisValue 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];
 		HatMask dpad = HatMask::CENTER;
 		HatMask dpad = HatMask::CENTER;
@@ -96,7 +96,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);
 
 
-	Input::JoyAxisValue axis_correct(const input_absinfo *p_abs, int p_value) const;
+	float axis_correct(const input_absinfo *p_abs, int p_value) const;
 };
 };
 
 
 #endif // JOYDEV_ENABLED
 #endif // JOYDEV_ENABLED

+ 3 - 14
platform/osx/joypad_osx.cpp

@@ -449,20 +449,9 @@ void JoypadOSX::poll_joypads() const {
 	}
 	}
 }
 }
 
 
-static const Input::JoyAxisValue axis_correct(int p_value, int p_min, int p_max) {
-	Input::JoyAxisValue jx;
-	if (p_min < 0) {
-		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;
+static float axis_correct(int p_value, int p_min, int p_max) {
+	// Convert to a value between -1.0f and 1.0f.
+	return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f;
 }
 }
 
 
 void JoypadOSX::process_joypads() {
 void JoypadOSX::process_joypads() {

+ 6 - 7
platform/uwp/joypad_uwp.cpp

@@ -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::JoyAxisValue JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
-	InputDefault::JoyAxisValue jx;
-
-	jx.min = p_trigger ? 0 : -1;
-	jx.value = (float)(p_negate ? -p_val : p_val);
-
-	return jx;
+float JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
+	if (p_trigger) {
+		// Convert to a value between -1.0f and 1.0f.
+		return 2.0f * p_val - 1.0f;
+	}
+	return (float)(p_negate ? -p_val : p_val);
 }
 }
 
 
 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) {

+ 1 - 1
platform/uwp/joypad_uwp.h

@@ -73,7 +73,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::JoyAxisValue 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);
 };
 };

+ 18 - 24
platform/windows/joypad_windows.cpp

@@ -448,33 +448,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);
 };
 };
 
 
-Input::JoyAxisValue JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
-	Input::JoyAxisValue jx;
+float JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
 	if (Math::abs(p_val) < MIN_JOY_AXIS) {
 	if (Math::abs(p_val) < MIN_JOY_AXIS) {
-		jx.min = p_trigger ? 0 : -1;
-		jx.value = 0.0f;
-		return jx;
+		return p_trigger ? -1.0f : 0.0f;
 	}
 	}
-	if (p_xinput) {
-		if (p_trigger) {
-			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;
+	if (!p_xinput) {
+		return (float)p_val / MAX_JOY_AXIS;
+	}
+	if (p_trigger) {
+		// Convert to a value between -1.0f and 1.0f.
+		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;
 	}
 	}
-	jx.min = -1;
-	jx.value = (float)p_val / MAX_JOY_AXIS;
-	return jx;
+	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) {

+ 1 - 1
platform/windows/joypad_windows.h

@@ -132,7 +132,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);
 
 
-	Input::JoyAxisValue 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;
 };
 };