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