Adicionar mapeamentos personalizados para controles

A biblioteca Game Controller mantém um banco de dados interno de controles, que é usado para configurar botões, layout de eixo de movimento, mapeamento para controles reconhecidos e um mapeamento padrão para controles não reconhecidos. A o banco de dados inclui muitos controles conhecidos, mas pode não incluir todos os dispositivos relevantes para um determinado jogo. A biblioteca Game Controller é compatível com personalização com funções que podem:

  • recuperar o banco de dados de mapeamento atual;
  • adicionar entradas ao banco de dados existente;
  • substituir as entradas atuais do banco de dados;
  • substituir todo o banco de dados atual por um novo.

Identificar um dispositivo

Os controles são identificados pelos valores productId e vendorId. Cada controlador reconhecido tem pelo menos uma entrada no banco de dados com um correspondentes a productId e vendorId. A estrutura de mapeamento do controle inclui campos que especificam um intervalo mínimo e máximo de API do Android qualificado para a entrada. Várias entradas com os mesmos productId e vendorId podem existir em no banco de dados, desde que tenham intervalos mínimos e máximos de API exclusivos.

Ler seus dados atuais de remapeamento

Use a função Paddleboat_getControllerRemapTableData para recuperar os dados de remapeamento atuais.

int32_t Paddleboat_getControllerRemapTableData(
   
const int32_t destRemapTableEntryCount,
   
Paddleboat_Controller_Mapping_Data* mappingData)

Paddleboat_getControllerRemapTableData retorna o número total de entradas de remapeamento presentes no banco de dados interno.

Parâmetro Descrição
destRemapTableEntryCount O tamanho da matriz de elementos Paddleboat_Controller_Mapping_Data transmitidos no parâmetro mappingData.
mappingData Um ponteiro para uma matriz de elementos Paddleboat_Controller_Mapping_Data.

Se destRemapTableEntryCount for menor que o número total de entradas de remapeamento, apenas o número de entradas especificadas por destRemapTableEntryCount são copiadas em mappingData.

Adicionar ou substituir dados de remapeamento

Use a função Paddleboat_addControllerRemapData para adicionar entradas de remapeamento ou substituir o banco de dados de remapeamento atual.

void Paddleboat_addControllerRemapData(
   
const Paddleboat_Remap_Addition_Mode addMode,
   
const int32_t remapTableEntryCount,
   
const Paddleboat_Controller_Mapping_Data* mappingData)
Parâmetro Descrição
addMode As regras de adição usadas para a operação. Os valores válidos são PADDLEBOAT_REMAP_ADD_MODE_DEFAULT ou PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL
remapTableEntryCount O tamanho da matriz de elementos Paddleboat_Controller_Mapping_Data transmitidos no parâmetro mappingData.
mappingData Um ponteiro para uma matriz de elementos Paddleboat_Controller_Mapping_Data.

Modos de adição

Se PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL for especificado em addMode, o banco de dados atual será excluído e substituído pelo conteúdo da nova matriz.

Se PADDLEBOAT_REMAP_ADD_MODE_DEFAULT for especificado em addMode, os seguintes critérios serão aplicados a cada elemento na matriz transmitida em mappingData:

  • Se um Paddleboat_getControllerRemapTableData for único, ou seja, se vendorId e productId ainda não existirem, ou existirem, mas em um intervalo sem sobreposição de minApi ou maxApi, a entrada será adicionada ao banco de dados interno.
  • Se o Paddleboat_getControllerRemapTableData não for único, isto é, se vendorId e productId existirem e houver uma sobreposição de minApi ou maxApi, ele substituirá a entrada existente no banco de dados interno.

A estrutura 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;

Exemplo de mapeamento

Veja a seguir um Paddleboat_Controller_Mapping_Data preenchido para descrever um controle Stadia do Google:

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