Dodaj niestandardowe mapowania urządzeń kontrolera

Biblioteka Game Controller prowadzi wewnętrzną bazę danych urządzeń sterujących, która służy do konfigurowania przycisków, układu osi ruchu, mapowania rozpoznanych kontrolerów i mapowania domyślnego dla nierozpoznanych kontrolerów. Baza danych zawiera wiele popularnych kontrolerów, ale może nie obejmować wszystkich urządzeń odpowiednich do danej gry. Biblioteka Game Controller obsługuje dostosowywanie za pomocą funkcji, które mogą:

  • Pobierz bieżącą bazę danych mapowania.
  • Dodawanie wpisów do istniejącej bazy danych.
  • Zastąp istniejące wpisy w bazie danych.
  • Zastąp całą bieżącą bazę danych nową.

Identyfikowanie urządzenia

Urządzenia sterujące są identyfikowane na podstawie wartości productIdvendorId. Każde rozpoznane urządzenie sterujące ma w bazie danych co najmniej 1 wpis z pasującymi wartościami productIdvendorId. Struktura mapowania kontrolera zawiera pola, które określają kwalifikujący się minimalny i maksymalny zakres interfejsu Android API dla wpisu. W bazie danych może być wiele wpisów z tymi samymi wartościami productIdvendorId, o ile mają one unikalne zakresy interfejsu API (minimalny i maksymalny).

Odczytywanie bieżących danych ponownego mapowania

Użyj funkcji Paddleboat_getControllerRemapTableData, aby pobrać bieżące dane ponownego mapowania.

int32_t Paddleboat_getControllerRemapTableData(
   const int32_t destRemapTableEntryCount,
   Paddleboat_Controller_Mapping_Data* mappingData)

Paddleboat_getControllerRemapTableData zwraca łączną liczbę wpisów remap w wewnętrznej bazie danych.

Parametr Opis
destRemapTableEntryCount Rozmiar tablicy elementów Paddleboat_Controller_Mapping_Data przekazanych w parametrze mappingData.
mappingData Wskaźnik do tablicy elementów Paddleboat_Controller_Mapping_Data.

Jeśli destRemapTableEntryCount jest mniejsza niż łączna liczba wpisów ponownego mapowania, do mappingData kopiowana jest tylko liczba wpisów określona przez destRemapTableEntryCount.

Dodawanie lub zastępowanie danych ponownego mapowania

Użyj funkcji Paddleboat_addControllerRemapData, aby dodać wpisy ponownego mapowania lub zastąpić bieżącą bazę danych ponownego mapowania.

void Paddleboat_addControllerRemapData(
   const Paddleboat_Remap_Addition_Mode addMode,
   const int32_t remapTableEntryCount,
   const Paddleboat_Controller_Mapping_Data* mappingData)
Parametr Opis
addMode Reguły dodawania użyte w operacji. Prawidłowe wartości to PADDLEBOAT_REMAP_ADD_MODE_DEFAULT lub PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL.
remapTableEntryCount Rozmiar tablicy elementów Paddleboat_Controller_Mapping_Data przekazanych w parametrze mappingData.
mappingData Wskaźnik do tablicy elementów Paddleboat_Controller_Mapping_Data.

Tryby dodawania

Jeśli w parametrze addMode podano wartość PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL, istniejąca baza danych zostanie usunięta i zastąpiona zawartością nowej tablicy.

Jeśli w parametrze addMode określono wartość PADDLEBOAT_REMAP_ADD_MODE_DEFAULT, do każdego elementu tablicy przekazywanej w parametrze mappingData stosowane są te kryteria:

  • Jeśli Paddleboat_getControllerRemapTableData jest unikalny (czyli vendorIdproductId jeszcze nie istnieją lub istnieją, ale mają niepokrywający się zakres minApi lub maxApi), wpis jest dodawany do wewnętrznej bazy danych.
  • Jeśli Paddleboat_getControllerRemapTableData nie jest unikalny (istnieją vendorIdproductId oraz występuje nakładanie się minApi lub maxApi), zastępuje istniejący wpis w wewnętrznej bazie danych.

Struktura Paddleboat_Controller_Mapping_Data jest następująca:

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;

Przykład mapowania

Poniżej przedstawiono Paddleboat_Controller_Mapping_Data wypełniony w celu opisania kontrolera 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
    }
};