The Game Controller library maintains an internal database of controller
devices, which is used to configure buttons, motion axis layout, mapping for
recognized controllers, and a default mapping for unrecognized controllers. The
database includes many popular controllers, but might not include all devices
relevant to a particular game. The Game Controller library supports customization
with functions that can:

- Retrieve the current mapping database.
- Add entries to the existing database.
- Replace existing database entries.
- Replace the entire current database with a new one.

## Identify a device

Controller devices are identified by their `productId` and `vendorId` values.
Each recognized controller device has at least one entry in the database with a
matching `productId` and `vendorId`. The controller mapping structure includes
fields that specify a qualifying minimum and maximum Android API range for the
entry. Multiple entries with the same `productId` and `vendorId` may exist in
the database as long as they have unique minimum and maximum API ranges.

## Read your current remap data

Use the [`Paddleboat_getControllerRemapTableData`](https://developer.android.com/reference/games/game-controller/group/paddleboat#paddleboat_getcontrollerremaptabledata) function to
retrieve the current remap data.  

    int32_t Paddleboat_getControllerRemapTableData(
       const int32_t destRemapTableEntryCount,
       Paddleboat_Controller_Mapping_Data* mappingData)

`Paddleboat_getControllerRemapTableData` returns the total number of remap
entries present in the internal database.

|         Parameter          |                                              Description                                               |
|----------------------------|--------------------------------------------------------------------------------------------------------|
| `destRemapTableEntryCount` | The array size of `Paddleboat_Controller_Mapping_Data` elements passed in the `mappingData` parameter. |
| `mappingData`              | A pointer to an array of `Paddleboat_Controller_Mapping_Data` elements.                                |

If `destRemapTableEntryCount` is smaller than the total number of remap entries,
only the number of entries specified by `destRemapTableEntryCount` are copied
into `mappingData`.

## Add or replace remap data

Use the [`Paddleboat_addControllerRemapData`](https://developer.android.com/reference/games/game-controller/group/paddleboat#paddleboat_addcontrollerremapdata) function to add
remap entries, or replace the current remap database.  

    void Paddleboat_addControllerRemapData(
       const Paddleboat_Remap_Addition_Mode addMode,
       const int32_t remapTableEntryCount,
       const Paddleboat_Controller_Mapping_Data* mappingData)

|       Parameter        |                                                                Description                                                                 |
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `addMode`              | The addition rules used for the operation. Valid values are `PADDLEBOAT_REMAP_ADD_MODE_DEFAULT` or `PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL` |
| `remapTableEntryCount` | The array size of `Paddleboat_Controller_Mapping_Data` elements passed in the `mappingData` parameter.                                     |
| `mappingData`          | A pointer to an array of `Paddleboat_Controller_Mapping_Data` elements.                                                                    |

### Addition modes

If `PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL` is specified in `addMode`, the
existing database is deleted and replaced by the contents of the new array.

If `PADDLEBOAT_REMAP_ADD_MODE_DEFAULT` is specified in `addMode`, the following
criteria are applied to each element in the array passed in `mappingData`:

- If a `Paddleboat_getControllerRemapTableData` is unique (in other words, the `vendorId` and `productId` does not already exist, or does exist but has a non-overlapping `minApi` or `maxApi` range), the entry is added to the internal database.
- If the `Paddleboat_getControllerRemapTableData` is not unique (`vendorId` and `productId` exists and there is a `minApi` or `maxApi` overlap), it *replaces* the existing entry in the internal database.

The `Paddleboat_Controller_Mapping_Data` structure is:  

    typedef struct Paddleboat_Controller_Mapping_Data {
        int16_t minimumEffectiveApiLevel; /** Min. API level for this entry */
        int16_t maximumEffectiveApiLevel; /** Max. API level, 0 = no max */
        int32_t vendorId; /** VendorID of the controller device for this entry */
        int32_t productId; /** ProductID of the controller device for this entry */
        int32_t flags; /** Flag bits, will be ORed with
                         * Paddleboat_Controller_Info.controllerFlags */

        /** AMOTION_EVENT_AXIS value for the corresponding Paddleboat control axis,
         *  or PADDLEBOAT_AXIS_IGNORED if unsupported. */
        uint16_t axisMapping[PADDLEBOAT_MAPPING_AXIS_COUNT];
        /** Button to set on positive or negative axis value,
         *  PADDLEBOAT_AXIS_BUTTON_IGNORED if none. */
        uint8_t axisPositiveButtonMapping[PADDLEBOAT_MAPPING_AXIS_COUNT];
        uint8_t axisNegativeButtonMapping[PADDLEBOAT_MAPPING_AXIS_COUNT];
        /** AKEYCODE_ value corresponding with the corresponding Paddleboat button.
         *  PADDLEBOAT_BUTTON_IGNORED if unsupported. */
        uint16_t buttonMapping[PADDLEBOAT_BUTTON_COUNT];
    } Paddleboat_Controller_Mapping_Data;

## Mapping example

The following illustrates a `Paddleboat_Controller_Mapping_Data` populated to
describe a [Google Stadia controller](https://store.google.com/product/stadia_controller):  

    #define PADDLEBOAT_AXIS_BUTTON_DPAD_UP 0
    #define PADDLEBOAT_AXIS_BUTTON_DPAD_LEFT 1
    #define PADDLEBOAT_AXIS_BUTTON_DPAD_DOWN 2
    #define PADDLEBOAT_AXIS_BUTTON_DPAD_RIGHT 3
    #define PADDLEBOAT_AXIS_BUTTON_L2 9
    #define PADDLEBOAT_AXIS_BUTTON_R2 12

    static const Paddleboat_Controller_Mapping_Data stadia_controller_map[] = {
        16, 0, 0x18d1, 0x9400, PADDLEBOAT_CONTROLLER_LAYOUT_STANDARD,
        {
            /* LX */ AMOTION_EVENT_AXIS_X,
            /* LY */ AMOTION_EVENT_AXIS_Y,
            /* RX */ AMOTION_EVENT_AXIS_Z,
            /* RY */ AMOTION_EVENT_AXIS_RZ,
            /* L1 */ PADDLEBOAT_AXIS_IGNORED,
            /* L2 */ AMOTION_EVENT_AXIS_BRAKE,
            /* R1 */ PADDLEBOAT_AXIS_IGNORED,
            /* R2 */ AMOTION_EVENT_AXIS_GAS,
            /* HX */ AMOTION_EVENT_AXIS_HAT_X,
            /* HY */ AMOTION_EVENT_AXIS_HAT_Y,
        },
        {
            /* LX */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* LY */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* RX */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* RY */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* L1 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* L2 */ PADDLEBOAT_AXIS_BUTTON_L2,
            /* R1 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* R2 */ PADDLEBOAT_AXIS_BUTTON_R2,
            /* HX */ PADDLEBOAT_AXIS_BUTTON_DPAD_RIGHT,
            /* HY */ PADDLEBOAT_AXIS_BUTTON_DPAD_DOWN,
        },
        {
            /* LX */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* LY */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* RX */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* RY */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* L1 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* L2 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* R1 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* R2 */ PADDLEBOAT_AXIS_BUTTON_IGNORED,
            /* HX */ PADDLEBOAT_AXIS_BUTTON_DPAD_LEFT,
            /* HY */ PADDLEBOAT_AXIS_BUTTON_DPAD_UP,
        },
        {
            /* UP     */ AKEYCODE_DPAD_UP,
            /* LEFT   */ AKEYCODE_DPAD_LEFT,
            /* DOWN   */ AKEYCODE_DPAD_DOWN,
            /* RIGHT  */ AKEYCODE_DPAD_RIGHT,
            /* A      */ AKEYCODE_BUTTON_A,
            /* B      */ AKEYCODE_BUTTON_B,
            /* X      */ AKEYCODE_BUTTON_X,
            /* Y      */ AKEYCODE_BUTTON_Y,
            /* L1     */ AKEYCODE_BUTTON_L1,
            /* L2     */ AKEYCODE_BUTTON_L2,
            /* L3     */ AKEYCODE_BUTTON_THUMBL,
            /* R1     */ AKEYCODE_BUTTON_R1,
            /* R2     */ AKEYCODE_BUTTON_R2,
            /* R3     */ AKEYCODE_BUTTON_THUMBR,
            /* SELECT */ AKEYCODE_BUTTON_SELECT,
            /* START  */ AKEYCODE_BUTTON_START,
            /* SYSTEM */ AKEYCODE_BUTTON_MODE,
            /* TOUCHP */ PADDLEBOAT_BUTTON_IGNORED,
            /* AUX1   */ PADDLEBOAT_BUTTON_IGNORED,
            /* AUX2   */ PADDLEBOAT_BUTTON_IGNORED,
            /* AUX3   */ PADDLEBOAT_BUTTON_IGNORED,
            /* AUX4   */ PADDLEBOAT_BUTTON_IGNORED
        }
    };