הוספת מיפויים של מכשירים עם בקר בהתאמה אישית

ספריית Game Controller מתחזקת מסד נתונים פנימי של מכשירי בקרה, שמשמש להגדרת לחצנים, פריסת ציר תנועה, מיפוי לבקרי משחקים מזוהים ומיפוי ברירת מחדל לבקרי משחקים לא מזוהים. המסד הנתונים כולל הרבה בקרים פופולריים, אבל יכול להיות שהוא לא כולל את כל המכשירים שרלוונטיים למשחק מסוים. ספריית בקר המשחקים תומכת בהתאמה אישית עם פונקציות שיכולות:

  • אחזור של מסד הנתונים הנוכחי של המיפוי.
  • הוספת רשומות למסד הנתונים הקיים.
  • החלפת רשומות קיימות במסד הנתונים.
  • להחליף את כל מסד הנתונים הנוכחי במסד נתונים חדש.

זיהוי מכשיר

מכשירי בקרה מזוהים לפי הערכים productId ו-vendorId שלהם. לכל בקר מוכר יש לפחות רשומה אחת במסד הנתונים עם productId וvendorId תואמים. מבנה מיפוי הבקר כולל שדות שמציינים טווח מינימלי ומקסימלי של Android API שמתאים לרשומה. יכולות להיות כמה רשומות עם אותם ערכים של productId ו-vendorId במסד הנתונים, כל עוד יש להן טווחי API ייחודיים של מינימום ומקסימום.

קריאה של נתוני המיפוי הנוכחיים

משתמשים בפונקציה Paddleboat_getControllerRemapTableData כדי לאחזר את נתוני המיפוי הנוכחיים.

int32_t Paddleboat_getControllerRemapTableData(
   const int32_t destRemapTableEntryCount,
   Paddleboat_Controller_Mapping_Data* mappingData)

Paddleboat_getControllerRemapTableData מחזירה את המספר הכולל של רשומות מיפוי מחדש שנמצאות במסד הנתונים הפנימי.

פרמטר תיאור
destRemapTableEntryCount גודל המערך של רכיבי Paddleboat_Controller_Mapping_Data שמועברים בפרמטר mappingData.
mappingData מצביע למערך של Paddleboat_Controller_Mapping_Data אלמנטים.

אם destRemapTableEntryCount קטן ממספר הרשומות הכולל של מיפוי מחדש, רק מספר הרשומות שצוין על ידי destRemapTableEntryCount מועתק אל mappingData.

הוספה או החלפה של נתוני מיפוי מחדש

משתמשים בפונקציה Paddleboat_addControllerRemapData כדי להוסיף רשומות מיפוי מחדש או להחליף את מסד הנתונים הנוכחי של המיפוי מחדש.

void Paddleboat_addControllerRemapData(
   const Paddleboat_Remap_Addition_Mode addMode,
   const int32_t remapTableEntryCount,
   const Paddleboat_Controller_Mapping_Data* mappingData)
פרמטר תיאור
addMode כללי ההוספה שמשמשים לפעולה. הערכים התקינים הם PADDLEBOAT_REMAP_ADD_MODE_DEFAULT או PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL
remapTableEntryCount גודל המערך של רכיבי Paddleboat_Controller_Mapping_Data שמועברים בפרמטר mappingData.
mappingData מצביע למערך של Paddleboat_Controller_Mapping_Data אלמנטים.

מצבי הוספה

אם מציינים את PADDLEBOAT_REMAP_ADD_MODE_REPLACE_ALL ב-addMode, מסד הנתונים הקיים נמחק ומוחלף בתוכן של המערך החדש.

אם מציינים את PADDLEBOAT_REMAP_ADD_MODE_DEFAULT ב-addMode, הקריטריונים הבאים חלים על כל רכיב במערך שמועבר ב-mappingData:

  • אם Paddleboat_getControllerRemapTableData הוא ייחודי (כלומר, Paddleboat_getControllerRemapTableData ו-productId עדיין לא קיימים, או שהם קיימים אבל יש להם טווח minApi או maxApi שלא חופף), הרשומה מתווספת למסד הנתונים הפנימי.vendorId
  • אם הערך של Paddleboat_getControllerRemapTableData לא ייחודי (vendorId ו-productId קיימים ויש חפיפה בין minApi ל-maxApi), הוא מחליף את הרשומה הקיימת במסד הנתונים הפנימי.

המבנה של 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;

דוגמה למיפוי

האיור הבא מציג Paddleboat_Controller_Mapping_Data שאוכלס כדי לתאר שלט ל-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
    }
};