فهرست منبع

map DPAD correctly

Billie Hilton 4 ماه پیش
والد
کامیت
dbfc159bef
3فایلهای تغییر یافته به همراه94 افزوده شده و 11 حذف شده
  1. 22 6
      memory-bank/current.md
  2. 54 4
      src/gamepad-mapper.js
  3. 18 1
      src/index.js

+ 22 - 6
memory-bank/current.md

@@ -1,14 +1,17 @@
 # Dawdlehorn - Current State
 
-## Current Task: Fix Gamepad Debug Triggers Display
-Fixed the triggers section of the Gamepad Debug interface to show proper button names (ZR, R, ZL, L for Nintendo controllers) instead of generic "L" and "R" labels.
+## Current Task: DPAD Axis Mapping and Dead Zone Immunity (COMPLETED)
+Implemented proper DPAD axis handling for Nintendo controllers, making the DPAD axis immune to dead zone filtering and mapping raw values to degrees for better usability.
 
 ## Current Task Checklist
 - [x] Read current project state from memory bank
-- [x] Examine gamepad debug code to understand triggers issue
-- [x] Update triggers section to show ZR, R, ZL, L instead of generic "triggers"
-- [x] Update memory bank with new controller information
-- [ ] Test the fix with browser
+- [x] Analyze DPAD axis implementation and dead zone filtering
+- [x] Implement DPAD axis immunity to dead zone filtering
+- [x] Map DPAD values according to specification
+- [x] Test the implementation
+- [x] Update DPAD mapping with correct raw values and degrees
+- [x] Update display to show DPAD directions in user-friendly format
+- [x] Update memory bank with changes
 
 ## Previous Task: Custom Gamepad Mapping Implementation (COMPLETED)
 - [x] Research gamepad API limitations and solutions
@@ -91,6 +94,19 @@ Fixed the triggers section of the Gamepad Debug interface to show proper button
 - **Trigger Names**: ZL (left trigger), ZR (right trigger), L (left bumper), R (right bumper)
 
 ## Recent Changes
+- **DPAD Axis Mapping Implementation**: Made DPAD axis immune to dead zone filtering
+- **Raw Value Mapping**: Mapped Nintendo controller DPAD 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°
+- **User-Friendly Display**: Updated DPAD display to show directional names (e.g., "Up-Right (45°)")
+- **Dead Zone Immunity**: DPAD axis now bypasses dead zone filtering for precise directional input
 - Fixed triggers display in gamepad debug interface
 - Now shows proper button names based on controller type:
   - Nintendo: ZL/ZR (triggers), L/R (bumpers)

+ 54 - 4
src/gamepad-mapper.js

@@ -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;

+ 18 - 1
src/index.js

@@ -151,7 +151,24 @@ class DawdlehornApp {
                 // Update debug displays with current gamepad state
                 this.elements.leftStickDisplay.textContent = `${this.gamepadState.leftStick.x.toFixed(2)}, ${this.gamepadState.leftStick.y.toFixed(2)}`;
                 this.elements.rightStickDisplay.textContent = `${this.gamepadState.rightStick.x.toFixed(2)}, ${this.gamepadState.rightStick.y.toFixed(2)}`;
-                this.elements.dpadDisplay.textContent = `${this.gamepadState.dpadAxis.toFixed(2)}`;
+                // Display DPAD direction in a user-friendly format
+                let dpadText;
+                if (this.gamepadState.dpadAxis === null) {
+                    dpadText = 'Neutral';
+                } else {
+                    const directionMap = {
+                        0: 'Right (0°)',
+                        45: 'Up-Right (45°)',
+                        90: 'Up (90°)',
+                        135: 'Up-Left (135°)',
+                        180: 'Left (180°)',
+                        225: 'Down-Left (225°)',
+                        270: 'Down (270°)',
+                        315: 'Down-Right (315°)'
+                    };
+                    dpadText = directionMap[this.gamepadState.dpadAxis] || `${this.gamepadState.dpadAxis}°`;
+                }
+                this.elements.dpadDisplay.textContent = dpadText;
                 // Update button display - show ALL pressed buttons dynamically
                 let buttonDisplay = '';