diff bindings.c @ 2317:e836cf11783b

Make deadzones configurable and bump up the default value
author Michael Pavone <pavone@retrodev.com>
date Sun, 02 Apr 2023 23:21:39 -0700
parents 59fd8aa352e2
children f8ce89498e11
line wrap: on
line diff
--- a/bindings.c	Sun Apr 02 23:21:04 2023 -0700
+++ b/bindings.c	Sun Apr 02 23:21:39 2023 -0700
@@ -64,6 +64,7 @@
 	keybinding positive;
 	keybinding negative;
 	int16_t    value;
+	int16_t    deadzone;
 } joyaxis;
 
 typedef struct {
@@ -144,7 +145,7 @@
 	}
 }
 
-void bind_axis(int joystick, int axis, int positive, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b)
+void bind_axis(int joystick, int axis, int positive, int deadzone, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b)
 {
 	if (joystick >= MAX_JOYSTICKS) {
 		return;
@@ -159,6 +160,7 @@
 		joysticks[joystick].axes = realloc(joysticks[joystick].axes, sizeof(joyaxis) * joysticks[joystick].num_axes);
 		memset(joysticks[joystick].axes + old_capacity, 0, (joysticks[joystick].num_axes - old_capacity) * sizeof(joyaxis));
 	}
+	joysticks[joystick].axes[axis].deadzone = deadzone;
 	if (positive) {
 		do_bind(&joysticks[joystick].axes[axis].positive, bind_type, subtype_a, subtype_b);
 	} else {
@@ -535,16 +537,14 @@
 	}
 }
 
-#define JOY_AXIS_THRESHOLD 2000
-
 void handle_joy_axis(int joystick, int axis, int16_t value)
 {
 	if (joystick >= MAX_JOYSTICKS  || axis >= joysticks[joystick].num_axes) {
 		return;
 	}
 	joyaxis *jaxis = joysticks[joystick].axes + axis;
-	int old_active = abs(jaxis->value) > JOY_AXIS_THRESHOLD;
-	int new_active = abs(value) > JOY_AXIS_THRESHOLD;
+	int old_active = abs(jaxis->value) > jaxis->deadzone;
+	int new_active = abs(value) > jaxis->deadzone;
 	int old_pos = jaxis->value > 0;
 	int new_pos = value > 0;
 	jaxis->value = value;
@@ -873,6 +873,8 @@
 	int       padnum;
 	tern_node *padbuttons;
 	tern_node *mousebuttons;
+	int       stick_deadzone;
+	int       trigger_deadzone;
 } pad_button_state;
 
 
@@ -905,7 +907,7 @@
 			bind_dpad(hostpadnum, render_dpad_part(hostbutton), render_direction_part(hostbutton), bindtype, subtype_a, subtype_b);
 			return;
 		} else if (hostbutton & RENDER_AXIS_BIT) {
-			bind_axis(hostpadnum, render_axis_part(hostbutton), hostbutton & RENDER_AXIS_POS, bindtype, subtype_a, subtype_b);
+			bind_axis(hostpadnum, render_axis_part(hostbutton), hostbutton & RENDER_AXIS_POS, state->trigger_deadzone, bindtype, subtype_a, subtype_b);
 			return;
 		}
 	}
@@ -936,6 +938,7 @@
 	}
 	char *end;
 	long axis = strtol(key, &end, 10);
+	int deadzone = state->stick_deadzone;
 	if (*end) {
 		//key is not a valid base 10 integer
 		axis = render_translate_input_name(hostpadnum, key, 1);
@@ -948,6 +951,9 @@
 			}
 			goto done;
 		}
+		if (!strcmp("lefttrigger", key) || !strcmp("righttrigger", key) || !strcmp("l2", key) || !strcmp("r2", key)) {
+			deadzone = state->trigger_deadzone;
+		}
 		if (axis & RENDER_DPAD_BIT) {
 			bind_dpad(hostpadnum, render_dpad_part(axis), render_direction_part(axis), bindtype, subtype_a, subtype_b);
 			goto done;
@@ -958,7 +964,7 @@
 			goto done;
 		}
 	}
-	bind_axis(hostpadnum, axis, positive, bindtype, subtype_a, subtype_b);
+	bind_axis(hostpadnum, axis, positive, deadzone, bindtype, subtype_a, subtype_b);
 done:
 	free(key);
 	return;
@@ -1020,7 +1026,7 @@
 }
 
 
-tern_node *get_binding_node_for_pad(int padnum)
+tern_node *get_binding_node_for_pad(int padnum, controller_info *info)
 {
 	if (padnum > MAX_JOYSTICKS) {
 		return NULL;
@@ -1038,8 +1044,7 @@
 		free(type_id);
 	}
 	if (!pad) {
-		controller_info info = get_controller_info(padnum);
-		char *key = make_controller_type_key(&info);
+		char *key = make_controller_type_key(info);
 		pad = tern_find_node(pads, key);
 		free(key);
 	}
@@ -1051,7 +1056,8 @@
 
 void handle_joy_added(int joystick)
 {
-	tern_node *pad = get_binding_node_for_pad(joystick);
+	controller_info info = get_controller_info(joystick);
+	tern_node *pad = get_binding_node_for_pad(joystick, &info);
 	if (!pad) {
 		return;
 	}
@@ -1078,7 +1084,7 @@
 					} else if (hostbutton & RENDER_AXIS_BIT) {
 						//SDL2 knows internally whether this should be a positive or negative binding, but doesn't expose that externally
 						//for now I'll just assume that any controller with axes for a d-pad has these mapped the "sane" way
-						bind_axis(joystick, render_axis_part(hostbutton), dir == 1 || dir == 3 ? 1 : 0, bindtype, subtype_a, subtype_b);
+						bind_axis(joystick, render_axis_part(hostbutton), dir == 1 || dir == 3 ? 1 : 0, info.stick_deadzone, bindtype, subtype_a, subtype_b);
 					} else {
 						bind_button(joystick, hostbutton, bindtype, subtype_a, subtype_b);
 					}
@@ -1086,22 +1092,19 @@
 			}
 		}
 	}
+	pad_button_state state = {
+		.padnum = joystick,
+		.padbuttons = get_pad_buttons(),
+		.mousebuttons = get_mouse_buttons(),
+		.stick_deadzone = info.stick_deadzone,
+		.trigger_deadzone = info.trigger_deadzone
+	};
 	tern_node *button_node = tern_find_node(pad, "buttons");
 	if (button_node) {
-		pad_button_state state = {
-			.padnum = joystick,
-			.padbuttons = get_pad_buttons(),
-			.mousebuttons = get_mouse_buttons()
-		};
 		tern_foreach(button_node, process_pad_button, &state);
 	}
 	tern_node *axes_node = tern_find_node(pad, "axes");
 	if (axes_node) {
-		pad_button_state state = {
-			.padnum = joystick,
-			.padbuttons = get_pad_buttons(),
-			.mousebuttons = get_mouse_buttons()
-		};
 		tern_foreach(axes_node, process_pad_axis, &state);
 	}
 }