|
|
@@ -298,14 +298,21 @@ export class GamepadMapper {
|
|
|
const axisName = mapping[axisIndex];
|
|
|
if (!axisName) return;
|
|
|
|
|
|
- // Apply deadzone
|
|
|
- const processedValue = this.applyDeadzone(axisValue);
|
|
|
- const previousValue = previousState.axes[axisName] || 0;
|
|
|
+ // DPAD_AXIS is immune to deadzone filtering and gets special processing
|
|
|
+ let processedValue;
|
|
|
+ if (axisName === 'DPAD_AXIS') {
|
|
|
+ processedValue = this.processDpadAxis(axisValue);
|
|
|
+ } else {
|
|
|
+ // Apply deadzone to all other axes
|
|
|
+ processedValue = this.applyDeadzone(axisValue);
|
|
|
+ }
|
|
|
|
|
|
+ const previousValue = previousState.axes[axisName] || 0;
|
|
|
currentState.axes[axisName] = processedValue;
|
|
|
|
|
|
// Only emit events if value changed significantly
|
|
|
- if (Math.abs(processedValue - previousValue) > 0.01) {
|
|
|
+ const threshold = axisName === 'DPAD_AXIS' ? 0.001 : 0.01;
|
|
|
+ if (Math.abs(processedValue - previousValue) > threshold) {
|
|
|
this.emit('axischange', {
|
|
|
gamepadIndex: gamepad.index,
|
|
|
axis: axisName,
|
|
|
@@ -316,6 +323,49 @@ export class GamepadMapper {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ processDpadAxis(rawValue) {
|
|
|
+ // DPAD axis mapping for Nintendo controllers (raw values to degrees):
|
|
|
+ // 1.29 = neutral (not pressed) -> null
|
|
|
+ // 0.14 = down -> 270°
|
|
|
+ // -0.14 = down right -> 315°
|
|
|
+ // -0.43 = right -> 0°
|
|
|
+ // -0.71 = up right -> 45°
|
|
|
+ // -1 = up -> 90°
|
|
|
+ // 1 = up left -> 135°
|
|
|
+ // 0.71 = left -> 180°
|
|
|
+ // 0.43 = down left -> 225°
|
|
|
+
|
|
|
+ // Use tolerance for floating point comparison
|
|
|
+ const tolerance = 0.05;
|
|
|
+
|
|
|
+ // Check for neutral position first
|
|
|
+ if (Math.abs(rawValue - 1.29) < tolerance) {
|
|
|
+ return null; // Not pressed
|
|
|
+ }
|
|
|
+
|
|
|
+ // Map raw values to degrees
|
|
|
+ if (Math.abs(rawValue - (-0.43)) < tolerance) {
|
|
|
+ return 0; // Right
|
|
|
+ } else if (Math.abs(rawValue - (-0.71)) < tolerance) {
|
|
|
+ return 45; // Up right
|
|
|
+ } else if (Math.abs(rawValue - (-1)) < tolerance) {
|
|
|
+ return 90; // Up
|
|
|
+ } else if (Math.abs(rawValue - 1) < tolerance) {
|
|
|
+ return 135; // Up left
|
|
|
+ } else if (Math.abs(rawValue - 0.71) < tolerance) {
|
|
|
+ return 180; // Left
|
|
|
+ } else if (Math.abs(rawValue - 0.43) < tolerance) {
|
|
|
+ return 225; // Down left
|
|
|
+ } else if (Math.abs(rawValue - 0.14) < tolerance) {
|
|
|
+ return 270; // Down
|
|
|
+ } else if (Math.abs(rawValue - (-0.14)) < tolerance) {
|
|
|
+ return 315; // Down right
|
|
|
+ }
|
|
|
+
|
|
|
+ // Return null for unrecognized values (treat as neutral)
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
applyDeadzone(value) {
|
|
|
if (Math.abs(value) < this.config.deadzone) {
|
|
|
return 0;
|