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
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
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, thevendorId
andproductId
does not already exist, or does exist but has a non-overlappingminApi
ormaxApi
range), the entry is added to the internal database. - If the
Paddleboat_getControllerRemapTableData
is not unique (vendorId
andproductId
exists and there is aminApi
ormaxApi
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:
#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
}
};