שימוש בספרייה של בקר המשחקים

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

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

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

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Paddleboat_init מקבלת שני פרמטרים:

  • מצביע ל-JNIEnv שמצורף לשרשור הנוכחי
  • הפניה לאובייקט JNI של מחלקה נגזרת Context.jobject כל אובייקט של מחלקה נגזרת הוא תקף, כולל, בין היתר, Context Activity,‏ NativeActivity או GameActivity.

הפונקציה Paddleboat_init מחזירה PADDLEBOAT_NO_ERROR אם האתחול הצליח, אחרת היא מחזירה קוד שגיאה מתאים.

אפשר להשתמש ב-Paddleboat_isInitialized כדי לבדוק אם הספרייה GameController הופעלה בהצלחה. היא מחזירה ערך בוליאני. אם הערך הוא true, ה-API זמין לשימוש.

bool Paddleboat_isInitialized()

לפני שמסיימים את האפליקציה, משתמשים בפונקציה Paddleboat_destroy כדי להשבית את ספריית בקר המשחקים. הפונקציה מקבלת פרמטר יחיד, מצביע ל-JNIEnv שמצורף לשרשור הנוכחי. יכול להיות שיתקשרו שוב אל Paddleboat_init אחרי Paddleboat_destroy.

void Paddleboat_destroy(JNIEnv *env)

דיווח לספרייה על אירועים במחזור החיים

ספריית בקר המשחק צריכה לקבל מידע על מחזור החיים של הפעילות onStop ועל אירועים של onStart. קוראים לפונקציות Paddleboat_onStop ו Paddleboat_onStart מתוך קוד הטיפול באירועי ההתחלה והעצירה. שתי הפונקציות מקבלות פרמטר יחיד: מצביע ל-JNIEnv שמצורף לשרשור הנוכחי.

void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)

רישום או הסרה של קריאה חוזרת (callback) של סטטוס בקר

ספריית Game Controller משתמשת בקריאה חוזרת (callback) של סטטוס הבקר כדי להודיע למשחק כשהבקר מחובר או מנותק. הוא תומך רק בקריאה חוזרת אחת של סטטוס בקר בכל פעם.

  • כדי לרשום קריאה חוזרת לסטטוס של בקר או להחליף קריאה חוזרת שכבר רשומה בפונקציית קריאה חוזרת חדשה, צריך לקרוא לפונקציה Paddleboat_setControllerStatusCallback.
  • כדי להסיר קריאה חוזרת שרשומה כרגע, מעבירים NULL או nullptr.
  • הפרמטר userData הוא מצביע אופציונלי לנתונים שהוגדרו על ידי המשתמש. הפרמטר userData יועבר לפונקציית הקריאה החוזרת. הסמן הזה נשמר באופן פנימי עד שהוא משתנה על ידי קריאה עוקבת אל Paddleboat_setControllerStatusCallback.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
  statusCallback, void *userData)

חתימת הפונקציה של פונקציית הקריאה החוזרת היא:

typedef void (*Paddleboat_ControllerStatusCallback)(
  const int32_t controllerIndex,
  const Paddleboat_ControllerStatus controllerStatus,
  void *userData)
פרמטר תיאור
controllerIndex האינדקס של בקר המשחקים שיזם את הקריאה החוזרת. הערך יהיה בין 0 ל-
PADDLEBOAT_MAX_CONTROLLERS - 1
controllerStatus ערך enum של PADDLEBOAT_CONTROLLER_JUST_CONNECTED או
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED.
userData מצביע אופציונלי (יכול להיות NULL) לנתונים שהוגדרו על ידי המשתמש, שצוינו בקריאה האחרונה אל Paddleboat_setControllerStatusCallback.

התקשרות לפונקציית העדכון של ספריית בקר המשחקים

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

void Paddleboat_update(JNIEnv *env)

עיבוד אירועים

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

ספריית Game Controller תומכת בשני סוגים של אירועי קלט: AInputEvents ואירועי קלט של GameActivity.

עיבוד של AInputEvent

המשחק צריך להעביר את AInputEvents על ידי קריאה ל-Paddleboat_processInputEvent מקוד הטיפול באירועים.

int32_t Paddleboat_processInputEvent(const AInputEvent *event)

Paddleboat_processInputEvent יוחזר 0 אם המערכת התעלמה מהאירוע, ו-1 אם האירוע עבר עיבוד ונצרך על ידי ספריית בקר המשחק.

עיבוד אירועים של GameActivity

אם המשחק שלכם משתמש ב-GameActivity, צריך להעביר את האירועים GameActivityKeyEvent ו-GameActivityMotionEvent על ידי קריאה ל-Paddleboat_processGameActivityKeyInputEvent או ל-Paddleboat_processGameActivityMotionInputEvent מקוד הטיפול באירועים.

int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
                                                    const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
                                                       const size_t eventSize)
פרמטר תיאור
event מצביע למבנה GameActivityKeyEvent או GameActivityMotionEvent, בהתאם לפונקציה שמופעלת.
eventSize הגודל בבייט של מבנה האירוע שמועבר בפרמטר event.

שתי הפונקציות יחזירו 0 אם המערכת התעלמה מהאירוע, ו-1 אם הספרייה של בקר המשחק עיבדה את האירוע והשתמשה בו.

כדי להשתמש במאפיין GameActivity, צריך לציין את ציר התנועה הפעיל באמצעות הפונקציה GameActivityPointerAxes_enableAxis. הקריאה ל-Paddleboat_getActiveAxisMask מחזירה מסיכת ביטים של ציר התנועה הפעיל כרגע שמשמש בבקרי המשחקים המחוברים.

uint64_t Paddleboat_getActiveAxisMask()

דוגמה לאופן הטיפול בבעיה הזו מופיעה בדוגמה של ספריית בקר המשחק שמשתמשת ב-GameActivity. הדוגמה סורקת את מסכת הצירים הפעילה ומעדכנת את GameActivity כשנעשה שימוש בצירים חדשים. הפונקציה הזו מיושמת בפונקציה NativeEngine::CheckForNewAxis().

void NativeEngine::CheckForNewAxis() {
    // Tell GameActivity about any new axis ids so it reports
    // their events
    const uint64_t activeAxisIds = Paddleboat_getActiveAxisMask();
    uint64_t newAxisIds = activeAxisIds ^ mActiveAxisIds;
    if (newAxisIds != 0) {
        mActiveAxisIds = activeAxisIds;
        int32_t currentAxisId = 0;
        while(newAxisIds != 0) {
            if ((newAxisIds & 1) != 0) {
                LOGD("Enable Axis: %d", currentAxisId);
                GameActivityPointerAxes_enableAxis(currentAxisId);
            }
            ++currentAxisId;
            newAxisIds >>= 1;
        }
    }
}

קריאת בקרים

ספריית Game Controller משתמשת בערך אינדקס כדי להתייחס לבקר ספציפי. הערכים התקינים של האינדקס נעים בין 0 ל-PADDLEBOAT_MAX_CONTROLLERS - 1. הפונקציה Paddleboat_getControllerStatus קובעת את הסטטוס של אינדקס בקר שצוין.

Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
  const int32_t controllerIndex)

יש שלוש פונקציות לקריאת מידע מבקר מקושר.

שם הבקר

הפונקציה Paddleboat_getControllerName function מקבלת שני פרמטרים של קלט: אינדקס של בקר, גודל של מאגר ופוינטר למאגר לאחסון מחרוזת שם הבקר. מחרוזת השם מעוצבת כמחרוזת C באמצעות קידוד UTF-8. השם של המכשיר מתקבל באופן פנימי באמצעות InputDevice.getName().

אם הפונקציה Paddleboat_getControllerName מאחזרת את השם בהצלחה, היא מחזירה את הערך PADDLEBOAT_NO_ERROR. אחרת, היא מחזירה קוד שגיאה מתאים.

Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
                                                  const size_t bufferSize,
                                                  char *controllerName);
פרמטר תיאור
controllerIndex האינדקס של בקר המשחקים שיזם את הקריאה החוזרת. הערך יהיה בין 0 ל-
PADDLEBOAT_MAX_CONTROLLERS - 1
bufferSize הגודל בבייטים של המאגר שעובר על ידי controllerName, מחרוזת השם תקוצר אם צריך כדי להתאים למאגר.
controllerName מצביע למאגר של bufferSize בייט לאחסון שם הבקר. השם יישמר כמחרוזת C בקידוד UTF-8.

פרטי מכשיר הבקרה

הפונקציה Paddleboat_getControllerInfo function מקבלת שני פרמטרים של קלט: אינדקס של בקר ומצביע למבנה Paddleboat_Controller_Info.

אם Paddleboat_Controller_Info אוכלס בהצלחה בנתונים, הפונקציה Paddleboat_getControllerInfo מחזירה PADDLEBOAT_NO_ERROR. אחרת, היא מחזירה קוד שגיאה מתאים.

Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
  Paddleboat_Controller_Info *controllerInfo)

המבנה Paddleboat_Controller_Info מכיל מידע ספציפי למכשיר על הבקר.

typedef struct Paddleboat_Controller_Info {
    uint32_t controllerFlags;
    int32_t controllerNumber;
    int32_t vendorId;
    int32_t productId;
    int32_t deviceId;
    Paddleboat_Controller_Thumbstick_Precision leftStickPrecision;
    Paddleboat_Controller_Thumbstick_Precision rightStickPrecision;
} Paddleboat_Controller_Info;

typedef struct Paddleboat_Controller_Thumbstick_Precision {
    float stickFlatX;
    float stickFlatY;
    float stickFuzzX;
    float stickFuzzY;
} Paddleboat_Controller_Thumbstick_Precision;

חלק מהערכים של חברי המבנה מאוכלסים בערכים שנלקחים מ-InputDevice שמשויך לבקר:

controllerNumber    -   InputDevice.getControllerNumber()
vendorId              - InputDevice.getVendorId()
productId             - InputDevice.getProductId()
deviceId              - InputDevice.getId()
  • ערך stickFlat מייצג את מידת השטיחות של המיקום המרכזי. הערך הזה שימושי בעיקר לחישוב אזור מת מרכזי כברירת מחדל במכשירים עם מרכוז עצמי.
  • הערך stickFuzz מייצג את טווח השגיאות המקובל, או את המרחק שבו הערך הנוכחי יכול להיות שונה מהערך בפועל בגלל רעשי רקע ומגבלות של רגישות המכשיר.

שני הערכים מנורמלים לערך מקסימלי של הציר 1.0 בכל אחד מהמאפיינים.

המאפיין controllerFlags member מכיל שילוב של דגלים בודדים עם מסכת ביטים וערכים של שילובים של כמה ביטים.

ביצוע פעולה לוגית AND של controllerFlags עם PADDLEBOAT_CONTROLLER_LAYOUT_MASK מניב ערך שאפשר להמיר לסוג enum‏ Paddleboat_ControllerButtonLayout. ה-enum הזה מציין את הסמלים ואת הפריסה של הלחצנים שמשמשים את בקר המשחקים.

enum Paddleboat_ControllerButtonLayout {
    //  Y
    // X B
    //  A
    PADDLEBOAT_CONTROLLER_LAYOUT_STANDARD = 0,
    //  △
    // □ ○
    //  x
    PADDLEBOAT_CONTROLLER_LAYOUT_SHAPES = 1,
    //  X
    // Y A
    //  B
    PADDLEBOAT_CONTROLLER_LAYOUT_REVERSE = 2,
    // X Y R1 L1
    // A B R2 L2
    PADDLEBOAT_CONTROLLER_LAYOUT_ARCADE_STICK = 3,
    PADDLEBOAT_CONTROLLER_LAYOUT_MASK = 3
};

הקבועים הבאים מגדירים ביטים של יכולות. כדי לקבוע אם בקר תומך ביכולת מסוימת, מבצעים פעולת AND לוגית של הקבוע המתאים מול controllerFlags. תוצאה שונה מאפס מציינת שהיכולת נתמכת על ידי הבקר.

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

אם הביט הזה מוגדר, לבקר יש משטח מגע משולב. אם לוח המגע נלחץ, הבקר מגדיר את הביט PADDLEBOAT_BUTTON_TOUCHPAD בשדה Paddleboat_Controller_Data.buttonsDown.

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

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

נתונים שעוברים לנאמני מידע

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

Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
  Paddleboat_Controller_Data *controllerData)

המבנה Paddleboat_Controller_Data מכיל את ערכי הקלט הנוכחיים של אמצעי הבקרה של הבקר.

typedef struct Paddleboat_Controller_Data {
    uint64_t timestamp;
    uint32_t buttonsDown;
    Paddleboat_Controller_Thumbstick leftStick;
    Paddleboat_Controller_Thumbstick rightStick;
    float triggerL1;
    float triggerL2;
    float triggerR1;
    float triggerR2;
    Paddleboat_Controller_Pointer virtualPointer;
} Paddleboat_Controller_Data;

typedef struct Paddleboat_Controller_Pointer {
    float pointerX;
    float pointerY;
} Paddleboat_Controller_Pointer;

typedef struct Paddleboat_Controller_Thumbstick {
    float stickX;
    float stickY;
} Paddleboat_Controller_Thumbstick;

טווחים של ערכים

סוג קלט טווח ערכים
ציר של מתאם לאגודל -1.0 עד 1.0
טריגרים 0.0 עד 1.0
סמנים וירטואליים 0.0 לרוחב או לגובה החלון (בפיקסלים)

פרטי המבנה

חבר/ה בארגון תיאור
buttonsDown מערך של שדות סיביות (bitfield) של סיביות לכל לחצן. קבועי המסכה הבינארית של הלחצנים מוגדרים בקובץ הכותרת paddleboat.h ומתחילים ב-PADDLEBOAT_BUTTON_.
timestamp. חותמת הזמן של אירוע הקלט האחרון של הבקר. חותמת הזמן היא במיקרו-שניות מאז תחילת התקופה של זמן מערכת.
virtualPointer מיקום מצביע וירטואלי. הערך תקף רק אם הדגל PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE מוגדר ב-controllerFlags, אחרת הערך יהיה 0.0, 0.0.