La libreria Game Controller gestisce un database interno di dispositivi di controllo, che viene utilizzato per configurare i pulsanti, il layout dell'asse di movimento, la mappatura per i controller riconosciuti e una mappatura predefinita per i controller non riconosciuti. Il database include molti controller popolari, ma potrebbe non includere tutti i dispositivi pertinenti a un determinato gioco. La libreria Game Controller supporta la personalizzazione con funzioni che possono:
- Recupera il database di mapping corrente.
 - Aggiungi voci al database esistente.
 - Sostituisci le voci di database esistenti.
 - Sostituisci l'intero database attuale con uno nuovo.
 
Identificare un dispositivo
I dispositivi di controllo sono identificati dai valori productId e vendorId.
Ogni dispositivo di controllo riconosciuto ha almeno una voce nel database con un productId e un vendorId corrispondenti. La struttura di mapping del controller include campi che specificano un intervallo API Android minimo e massimo qualificante per la voce. Nel database possono esistere più voci con lo stesso productId e vendorId, purché abbiano intervalli API minimi e massimi univoci.
Leggere i dati di rimappatura attuali
Utilizza la funzione Paddleboat_getControllerRemapTableData per
recuperare i dati di rimappatura attuali.
int32_t Paddleboat_getControllerRemapTableData(
   const int32_t destRemapTableEntryCount,
   Paddleboat_Controller_Mapping_Data* mappingData)
Paddleboat_getControllerRemapTableData restituisce il numero totale di voci di rimappatura
presenti nel database interno.
| Parametro | Descrizione | 
|---|---|
destRemapTableEntryCount
 | 
La dimensione dell'array di
Paddleboat_Controller_Mapping_Data elementi
passati nel parametro mappingData. | 
mappingData
 | 
Un puntatore a un array di
elementi Paddleboat_Controller_Mapping_Data. | 
Se destRemapTableEntryCount è inferiore al numero totale di voci di rimappatura,
in mappingData viene copiato solo il numero di voci specificato da destRemapTableEntryCount.
Aggiungere o sostituire i dati di rimappatura
Utilizza la funzione Paddleboat_addControllerRemapData per aggiungere
voci di rimappatura o sostituire il database di rimappatura corrente.
void Paddleboat_addControllerRemapData(
   const Paddleboat_Remap_Addition_Mode addMode,
   const int32_t remapTableEntryCount,
   const Paddleboat_Controller_Mapping_Data* mappingData)
| Parametro | Descrizione | 
|---|---|
addMode
 | 
Le regole di addizione utilizzate per l'operazione.
I valori validi sono
PADDLEBOAT_REMAP_ADD_MODE_DEFAULT o
PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL | 
remapTableEntryCount
 | 
La dimensione dell'array di
Paddleboat_Controller_Mapping_Data elementi
passati nel parametro mappingData. | 
mappingData
 | 
Un puntatore a un array di
elementi Paddleboat_Controller_Mapping_Data. | 
Modalità di addizione
Se PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL è specificato in addMode, il
database esistente viene eliminato e sostituito con i contenuti del nuovo array.
Se PADDLEBOAT_REMAP_ADD_MODE_DEFAULT è specificato in addMode, i seguenti
criteri vengono applicati a ogni elemento dell'array passato in mappingData:
- Se un 
Paddleboat_getControllerRemapTableDataè univoco (in altre parole, ilvendorIde ilproductIdnon esistono già o esistono ma hanno un intervallominApiomaxApinon sovrapposto), la voce viene aggiunta al database interno. - Se 
Paddleboat_getControllerRemapTableDatanon è univoco (vendorIdeproductIdesistono e si verifica una sovrapposizione diminApiomaxApi), sostituisce la voce esistente nel database interno. 
La struttura di Paddleboat_Controller_Mapping_Data è:
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;
Esempio di mappatura
Di seguito è riportato un Paddleboat_Controller_Mapping_Data compilato per
descrivere un controller Google Stadia:
#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
    }
};