/**
 * Controller remapping support for `useGamepad`.
 *
 * The browser's Gamepad API only guarantees a consistent layout when
 * `Gamepad.mapping === "standard"`. Many controllers — notably Nintendo Switch
 * Pro, Joy-Cons, and the Switch Online SNES/N64/Genesis pads — commonly report
 * an empty `mapping` string, which means the raw button and axis indices come
 * straight from the HID descriptor and do not match the W3C Standard Gamepad
 * layout. This module provides a small, extensible table of controller-specific
 * remaps so `useGamepad` can expose a consistent position-based API regardless
 * of controller brand.
 *
 * The name of each button in the standard layout (`clusterBottom`, `clusterRight`,
 * `clusterLeft`, `clusterTop`) refers to the physical position of the face
 * button, not the letter printed on it. So on an Xbox pad `clusterBottom === A`,
 * on a DualSense `clusterBottom === Cross`, and on a Nintendo pad
 * `clusterBottom === B`.
 */
/**
 * The standard button names exposed by `useGamepad` in non-XR mode, in the
 * order of the W3C Standard Gamepad button indices.
 */
export declare const standardButtonNames: readonly ["clusterBottom", "clusterRight", "clusterLeft", "clusterTop", "leftBumper", "rightBumper", "leftTrigger", "rightTrigger", "select", "start", "leftStickButton", "rightStickButton", "directionalTop", "directionalBottom", "directionalLeft", "directionalRight", "center"];
export type StandardButtonName = (typeof standardButtonNames)[number];
/**
 * Describes where to read a button's state from on a non-standard controller.
 *
 * - `{ button: n }` reads from `pad.buttons[n]`.
 * - `{ axis, ... }` reads from `pad.axes[axis]`. Useful for analog triggers
 *   that some controllers expose as an axis in `[-1, 1]` rather than a button
 *   in `[0, 1]`. The axis value is remapped into `[0, 1]`:
 *   - when `range` is `"unit"` (default) the raw value is treated as a button
 *     value in `[0, 1]` (anything < 0 is clamped to 0).
 *   - when `range` is `"signed"` the axis is assumed to rest at `-1` and reach
 *     `1` when fully pressed, and is normalised to `(raw + 1) / 2`.
 *
 *   `invert` flips the sign of the raw reading before normalisation.
 *   `pressThreshold` controls when the button reports `pressed: true`
 *   (default 0.5 on the normalised value).
 */
export type ButtonSource = {
    button: number;
} | {
    axis: number;
    range?: 'unit' | 'signed';
    invert?: boolean;
    pressThreshold?: number;
};
/**
 * Synthesizes directional button states (Top/Bottom/Left/Right) from a single
 * axis that encodes a hat switch. Many Nintendo-style controllers report the
 * D-pad this way on Chromium browsers, using `axes[9]` with eight quantized
 * values around the circle.
 *
 * Each direction field holds the axis values at which that direction should
 * be considered pressed. A diagonal (e.g. up-right) appears in both `up` and
 * `right`. Idle is implied by the absence of a match, so no special neutral
 * value is needed.
 */
export interface HatAxisMapping {
    axis: number;
    up: number[];
    right: number[];
    down: number[];
    left: number[];
    /** Absolute-value tolerance used when matching axis values. Default 0.1. */
    tolerance?: number;
}
/** Describes how a stick is read from two axes. */
export interface StickAxisMapping {
    xAxis: number;
    yAxis: number;
    invertX?: boolean;
    invertY?: boolean;
}
/**
 * A remap entry for a specific non-standard controller.
 *
 * Any field left undefined falls back to the W3C Standard Gamepad layout:
 * `buttons[0..16]` for the standard button indices, `axes[0..1]` for the
 * left stick, and `axes[2..3]` for the right stick.
 *
 * If `dpad` is set, the `directionalTop/Bottom/Left/Right` entries of
 * `buttons` are ignored and directional state is synthesised from the hat
 * axis instead.
 */
export interface GamepadMapping {
    /** Human-readable name for debugging. */
    name?: string;
    buttons?: Partial<Record<StandardButtonName, ButtonSource>>;
    leftStick?: StickAxisMapping;
    rightStick?: StickAxisMapping;
    dpad?: HatAxisMapping;
}
/**
 * A dictionary of controller remaps keyed by a canonical `vvvv:pppp`
 * signature (hex USB vendor and product IDs, lowercase) derived from
 * `Gamepad.id`.
 */
export type GamepadMappings = Record<string, GamepadMapping>;
/**
 * Parse a `Gamepad.id` string into a canonical `vvvv:pppp` signature.
 *
 * Chromium exposes `"Name (Vendor: VVVV Product: PPPP)"`, Firefox exposes
 * `"VVVV-PPPP-Name"`. Returns `null` if neither pattern matches, in which
 * case the caller cannot look up a remap and should fall back to the
 * standard layout.
 */
export declare const parseGamepadSignature: (id: string) => string | null;
/**
 * Built-in mappings for common non-standard controllers.
 *
 * Every browser/OS/connection combination can potentially report a controller
 * differently, so these entries target the most widely reported configurations
 * (Chromium browsers on recent macOS/Windows/Linux, USB and Bluetooth).
 * Users with different setups can override any entry by passing `mappings` to
 * `useGamepad`.
 *
 * Sources:
 * - W3C Gamepad Standard Mapping (https://www.w3.org/TR/gamepad/#remapping)
 * - SDL_GameControllerDB (https://github.com/mdqinc/SDL_GameControllerDB)
 * - Chromium `device/gamepad/gamepad_standard_mappings_*.cc` (per-platform
 *   remapping tables shipped inside the browser itself)
 */
export declare const builtinMappings: GamepadMappings;
/**
 * Look up a remap for the given `Gamepad`. Returns `null` when the pad already
 * uses the Standard Gamepad layout, when its id cannot be parsed into a
 * vendor/product signature, or when no mapping is registered for that pad.
 */
export declare const resolveMapping: (pad: Gamepad, userMappings: GamepadMappings | undefined, includeBuiltins: boolean) => GamepadMapping | null;
/**
 * Read a single button's state using an optional remap entry. Falls back to
 * `pad.buttons[defaultIndex]` when no remap is present. The synthesised return
 * for axis-sourced buttons is structurally compatible with `GamepadButton`.
 */
export declare const readButton: (pad: Gamepad, source: ButtonSource | undefined, defaultIndex: number) => GamepadButton | undefined;
/**
 * Read a stick's (x, y) using an optional remap. Falls back to the supplied
 * default axis indices and no inversion when no remap is present.
 */
export declare const readStick: (pad: Gamepad, mapping: StickAxisMapping | undefined, defaultXAxis: number, defaultYAxis: number) => {
    x: number;
    y: number;
};
/** Compute the four directional states from a hat-axis mapping. */
export declare const readHatDirections: (pad: Gamepad, hat: HatAxisMapping) => {
    up: boolean;
    right: boolean;
    down: boolean;
    left: boolean;
};
