Aggiungi mappature dei dispositivi controller personalizzate

La libreria dei controller di gioco gestisce un database interno dei dispositivi controller, che viene utilizzato per configurare pulsanti, layout degli assi di movimento, mappatura per i controller riconosciuti e una mappatura predefinita per i controller non riconosciuti. Il database include molti controller tra i più diffusi, ma potrebbe non includere tutti i dispositivi pertinenti a un determinato gioco. La libreria del controller di gioco supporta la personalizzazione con funzioni che possono:

  • Recupera il database di mapping attuale.
  • Aggiungi voci al database esistente.
  • Sostituisci le voci di database esistenti.
  • Sostituisci l'intero database attuale con uno nuovo.

Identifica un dispositivo

I dispositivi controller sono identificati dai rispettivi valori productId e vendorId. Ogni dispositivo controller riconosciuto ha almeno una voce nel database con productId e vendorId corrispondenti. La struttura di mappatura del controller include campi che specificano un intervallo minimo e massimo consentito per le API Android per la voce. Nel database possono esistere più voci con gli stessi productId e vendorId, purché dispongano di intervalli API minimi e massimi univoci.

Leggere i tuoi dati di rimappa correnti

Utilizza la funzione Paddleboat_getControllerRemapTableData per recuperare i dati di rimappa correnti.

int32_t Paddleboat_getControllerRemapTableData(
   const int32_t destRemapTableEntryCount,
   Paddleboat_Controller_Mapping_Data* mappingData)

Paddleboat_getControllerRemapTableData restituisce il numero totale di voci rimappate presenti nel database interno.

Parametro Descrizione
destRemapTableEntryCount La dimensione dell'array di elementi Paddleboat_Controller_Mapping_Data passata nel parametro mappingData.
mappingData Un puntatore a un array di elementi Paddleboat_Controller_Mapping_Data.

Se destRemapTableEntryCount è inferiore al numero totale di voci rimappate, solo il numero di voci specificato da destRemapTableEntryCount viene copiato in mappingData.

Aggiungi o sostituisci dati di rimappa

Utilizza la funzione Paddleboat_addControllerRemapData per aggiungere voci di rimappa o sostituire il database di rimappa 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 aggiunta 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 elementi Paddleboat_Controller_Mapping_Data passata nel parametro mappingData.
mappingData Un puntatore a un array di elementi Paddleboat_Controller_Mapping_Data.

Modalità di aggiunta

Se PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL è specificato in addMode, il database esistente viene eliminato e sostituito dai contenuti del nuovo array.

Se PADDLEBOAT_REMAP_ADD_MODE_DEFAULT è specificato in addMode, vengono applicati i seguenti criteri a ciascun elemento nell'array trasmesso in mappingData:

  • Se Paddleboat_getControllerRemapTableData è univoco (in altre parole, vendorId e productId non esistono già o esistono ma hanno un intervallo minApi o maxApi non sovrapposto), la voce viene aggiunta al database interno.
  • Se Paddleboat_getControllerRemapTableData non è univoco (vendorId e productId esiste e vi è una sovrapposizione minApi o maxApi), sostituisce la voce esistente nel database interno.

La struttura 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 esempio di Paddleboat_Controller_Mapping_Data per la descrizione di 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
    }
};