Skip to content

📄Technical Documentation: Trigger Effect Mapping

rafaelvaloto edited this page Dec 21, 2025 · 1 revision

This document consolidates research and debugging efforts on the adaptive trigger effects of the DualSense controller. It details the official, unofficial (discovered via research), vestigial (inherited from previous firmware/protocol versions), and debug operation modes.

The main focus is the structure of the data packets sent to the controller (Report ID 0x31, trigger offset) and the correlation between HEX, Binary values, and the resulting physical behavior.


Table of contents

    1. Master Effect Identification Table
    1. Detailed Effect Analysis & Binary Comparison
    • 2.1 Official Modes (0x20+)
    • 2.2 Discovered / Unofficial Modes
    • 2.3 Vestigial (Legacy) Modes
    1. Conclusions
    1. Binary Compression Patterns
  • References

1. Master Effect Identification Table

Category Effect (UI / Technical) HEX ID Dec Short description
Official Off 0x00 0 Turns off all effects (neutral).
Official Feedback (Resistance) 0x21 33 Continuous resistance. Bit-packed params (zone 0–9, strength 0–8).
Official Weapon 0x25 37 Simulates trigger "break point". Start/end and strength are packed.
Official Vibration 0x26 38 Trigger vibration. Packed: zone, amplitude, frequency.
Unofficial Bow 0x22 34 Resistance with a snap-back / bow behavior.
Unofficial Galloping 0x23 35 Oscillating rhythmic (gallop) pattern.
Unofficial Machine 0x27 39 Complex vibration alternating two amplitudes.
Vestigial Simple_Feedback 0x01 1 Legacy Feedback — uses full bytes (0–255).
Vestigial Simple_Weapon 0x02 2 Legacy Weapon / "GameCube Click" — 8-bit params.
Vestigial Simple_Vibration 0x06 6 Legacy Vibration — 8-bit params.
Debug DebugFC 0xFC 252 Internal calibration / debug.
Debug DebugFD 0xFD 253 Internal calibration / debug.
Debug DebugFE 0xFE 254 Internal calibration / debug.

2. Detailed Effect Analysis & Binary Comparison

Each effect below is broken down into bytes and illustrated with real log examples plus binary views that reveal bit‑packing.

2.1 Official Modes (0x20+)

Official modes are used by commercial titles and rely heavily on bit‑packing: single bytes often encode multiple parameters.

  • 0x00 — Off
    Disables resistance (neutral).

    Example (off):

    [00 00 00 00 00 00 00 00 00 00]
    Binary: 00000000 00000000 ...
    
  • 0x21 — Official Feedback (Inclination)
    Linear resistance with configurable start/end forces.

    Common structure:

    [21] [Start Pos / Extra] [End Pos / Extra] [Start Strength] [End Strength] ...
    

    Example 1 — Simple Feedback:

    HEX: 21 C7 00 FF 01
    BIN: 00100001 11000111 00000000 11111111 00000001
    

    Example 2 — Inclination:

    HEX: 21 F8 03 00 48
    BIN: 00100001 11111000 00000011 00000000 01001000
    
  • 0x25 — Official Weapon (Semi-Automatic)
    Simulates a trigger with a break point; structure is highly packed. Adjacent positions map to non-linear bit patterns (likely zones/flags), not simple +1 increments.

    Examples (end positions with strength 07):

    Position 8: 25 04 01 07
    BIN:       00100101 00000100 00000001 00000111
    
    Position 7: 25 84 00 07
    BIN:       00100101 10000100 00000000 00000111
    
    Position 6: 25 44 00 07
    BIN:       00100101 01000100 00000000 00000111
    

    Observation: changes are bitwise; likely each bit maps to a physical or logical "zone".

  • 0x26 — Official Vibration
    Continuous vibration; parameters include start position, amplitude and frequency.

    Example:

    HEX: 26 80 03 00 00 A0 2D
    BIN: 00100110 10000000 00000011 00000000 ...
    

2.2 Discovered / Unofficial Modes

These modes are present in firmware but not documented in public SDKs.

  • 0x22 — Bow (detailed reverse engineering)
    Mode 0x22 is complex. Byte 2 (B2) acts as the "brain" and determines how Byte 1 (B1) is interpreted and whether a click is enabled.

    High-level rules:

    • B2 identifies two families:
      • Family A — Single Position (B2 = 0x01): B1 selects a preset; click enabled.
      • Family B — Range (B2 = 0x00 or 0x02): B1 splits into nibbles: [END][START]; no click.

    B1 interpretation:

    • If B2 == 0x01 (Single Position):

      1. Check low nibble (bits 3–0). If non-zero, low nibble maps to presets:
        • 0x02 → "High"
        • 0x04 → "Medium"
        • 0x08 → "Low" (e.g., 0x82, 0x92, 0xA2 are treated as 0x02)
      2. If low nibble == 0x0, use high nibble for fine adjustments near the end:
        • 0x10 (high) → End +3
        • 0x20 (high) → End +2
        • 0x80 (high) → End
    • If B2 == 0x00 or 0x02 (Range):

      • B1 = [High nibble: END] [Low nibble: START]

    B3 — Spring profile & force:

    • B3 = [bits7-4: spring profile] [bits3-0: force magnitude]
    • If bit 7 of B3 is set (e.g., 0x8_, 0xA_) the magnitude nibble may be ignored (disable flag).
    • Force magnitude: 0x0 = min, 0xF = max.

    Example:

    Command: 22 82 00 3F
    Breakdown:
      22 = Bow
      82 = B1 -> high=8 (END=8), low=2 (START=2)
      00 = B2 -> Range (no click)
      3F = B3 -> spring profile 3 (high nibble) + force 0xF (max)
    Result: Strong, clickless bow from position 2 to 8.
    
  • 0x23 — Galloping
    Rhythmic effect. A "split byte" (nibbles) defines two feet (Foot1, Foot2).

    Example:

    HEX: 23 0A 00 2F 05
    BIN: 00100011 00001010 00000000 00101111 00000101
    Split byte 0x2F -> upper nibble 0x2 (foot1 = 2), lower nibble 0xF (foot2 = 15)
    Frequency: 0x05 (~5 Hz)
    
  • 0x27 — Machine
    Complex vibration alternating two amplitudes, with frequency and period.

    • Notes:
      • Start_Zone: Dropdown (int) { Start = 130 (0x82), Middle = 132 (0x84), End = 128 (0x80), MidLow = 136 (0x88) }
      • Behavior_Flag: Dropdown (int) { EndAtPos = 1, KeepEffect = 2 }
      • Force_Amplitude (High Nibble) must be 1-3. Amplitude (Low Nibble) must be 10-15.
      • Period: Slider (int) 0 - 20
      • Frequency: Slider (int) 0 - 40 (ex: 2)

    Example:

    HEX: 27 02 02 3A 0A 05 00
    Fields: [27] [Start_Zone] [Behavior_Flag] [Force_Amplitude] [Period] [Frequency]
    

    Note: Frequency observed up to ~0x28 (≈ 40 Hz) and Period up to ~20 (decimal).


2.3 Vestigial (Legacy) Modes

Older, simpler modes using full bytes (0–255) rather than bit‑packed fields. Useful for simple testing or fallback behavior.

  • 0x02 — Simple Weapon / GameCube Click (example):
    HEX: 02 90 A0 FF 00 00 00 00 00 00
    BIN: 00000010 10010000 10100000 11111111 ...
    

3. Conclusions from Research & Debugging

  • Data compression (bit‑packing) is heavily used in official modes: position and strength are not linear decimal→HEX mappings. Many bytes encode multiple fields or flags.
  • Nibbles are commonly used to pack two small independent parameters into one byte (e.g., galloping feet).
  • Mode 0x22 (Bow) has conditional logic and distinct families: it is not a trivial variation of 0x21.
  • Legacy modes (0x01, 0x02, 0x06) remain available and use full‑byte values, which are simpler to implement but less compact.

4. Binary Compression Patterns

4.1 Split-Byte (Nibbles)

  • Packs two values (0–15) into a single byte:
    • Example: 0x2F → upper nibble 0x2 (2), lower nibble 0xF (15)

4.2 Non‑linear Compression (Bitmasking) — Weapon (0x25)

  • Positions change via bit shifts; each bit may represent a zone or flag.

    Example:

    Target Position | Position Bytes (HEX) | Combined binary (16 bits)
    8               | 04 01                | 00000100 00000001  (bit10, bit0 active)
    7               | 84 00                | 10000100 00000000  (bit15, bit10 active)
    6               | 44 00                | 01000100 00000000  (bit14, bit10 active)
    

4.3 Packed Position Patterns — Feedback (0x21)

  • Different start positions produce distinct hex values; they make sense when read in binary (multiple bits active to represent zones).

  • ↩️ Return to home page


Back to the Main Repository