Korzystanie z biblioteki kontrolerów gier

Użyj poniższych funkcji, aby dodać obsługę kontrolera do gier za pomocą biblioteki kontrolerów gier.

Inicjowanie i niszczenie biblioteki kontrolera gier

Aby zainicjować bibliotekę kontrolera gier, użyj funkcji Paddleboat_init.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Funkcja Paddleboat_init przyjmuje 2 parametry:

Jeśli inicjowanie się udało, Paddleboat_init zwraca wartość PADDLEBOAT_NO_ERROR. W przeciwnym razie zwracany jest odpowiedni kod błędu.

Aby sprawdzić, czy biblioteka kontrolera gier została zainicjowana, możesz użyć narzędzia Paddleboat_isInitialized. Zwraca wartość logiczną. Jeśli ma wartość true (prawda), interfejs API jest dostępny do użycia.

bool Paddleboat_isInitialized()

Przed zakończeniem aplikacji wyłącz bibliotekę kontrolera gier za pomocą funkcji Paddleboat_destroy. Funkcja przyjmuje pojedynczy parametr – wskaźnik do JNIEnv dołączonego do bieżącego wątku. Numer Paddleboat_init może zostać ponownie wywołany po Paddleboat_destroy.

void Paddleboat_destroy(JNIEnv *env)

Informuj bibliotekę zdarzeń cyklu życia

W bibliotece kontrolera gier należy informować o cyklach życia aktywności onStop i zdarzeniach onStart. Wywołaj funkcje Paddleboat_onStop i Paddleboat_onStart z kodu obsługi zdarzeń zatrzymania i rozpoczęcia. Obie funkcje przyjmują pojedynczy parametr: wskaźnik do JNIEnv dołączony do bieżącego wątku.

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

Rejestrowanie lub usuwanie wywołania zwrotnego stanu kontrolera

Biblioteka kontrolera gier korzysta z wywołania zwrotnego stanu kontrolera, aby powiadamiać grę o podłączeniu lub odłączeniu kontrolera. Obsługuje tylko 1 wywołanie stanu kontrolera naraz.

  • Aby zarejestrować wywołanie zwrotne stanu kontrolera lub zastąpić wcześniej zarejestrowane wywołanie zwrotne nową funkcją wywołania zwrotnego, wywołaj funkcję Paddleboat_setControllerStatusCallback.
  • Aby usunąć obecnie zarejestrowane wywołanie zwrotne, musisz przesłać polecenie NULL lub nullptr.
  • Parametr userData jest opcjonalnym wskaźnikiem danych zdefiniowanych przez użytkownika. Parametr userData jest przekazywany do funkcji wywołania zwrotnego. Ten wskaźnik jest zachowywany wewnętrznie, dopóki nie zostanie zmieniony przez kolejne wywołanie Paddleboat_setControllerStatusCallback.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
  statusCallback, void *userData)

Podpis funkcji wywołania zwrotnego:

typedef void (*Paddleboat_ControllerStatusCallback)(
  const int32_t controllerIndex,
  const Paddleboat_ControllerStatus controllerStatus,
  void *userData)
Parametr Opis
controllerIndex Indeks kontrolera, który zainicjował wywołanie zwrotne. Będzie mieć wartość z zakresu od 0 do
. PADDLEBOAT_MAX_CONTROLLERS - 1
controllerStatus Wartość wyliczenia PADDLEBOAT_CONTROLLER_JUST_CONNECTED lub
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED.
userData Opcjonalny wskaźnik (może mieć wartość NULL) do danych zdefiniowanych przez użytkownika określonych w ostatnim wywołaniu funkcji Paddleboat_setControllerStatusCallback.

Wywoływanie funkcji aktualizacji biblioteki kontrolera gier

Funkcja aktualizacji biblioteki kontrolera gier (Paddleboat_update) powinna być wywoływana raz na ramkę z grą, najlepiej tuż przed jej rozpoczęciem. Funkcja przyjmuje pojedynczy parametr – wskaźnik do JNIEnv dołączony do bieżącego wątku.

void Paddleboat_update(JNIEnv *env)

Przetwarzanie zdarzeń

Gdy odbierasz zdarzenia wejściowe, gra musi przekazać je do biblioteki kontrolerów gier w celu sprawdzenia. Biblioteka kontrolera gier ocenia, czy z jednym z zarządzanych urządzeń jest powiązane zdarzenie wejściowe. Zdarzenia z urządzeń zarządzanych są przetwarzane i wykorzystywane.

Biblioteka kontrolera gier obsługuje 2 typy zdarzeń wejściowych: AInputEvents i GameActivity.

Przetwarzanie AInputEvent

Gra powinna przekierować dyrektywę AInputEvents, wywołując metodę Paddleboat_processInputEvent z kodu obsługi zdarzenia.

int32_t Paddleboat_processInputEvent(const AInputEvent *event)

Funkcja Paddleboat_processInputEvent zwraca wartość 0, jeśli zdarzenie zostało zignorowane, lub 1, jeśli zdarzenie zostało przetworzone i użyte przez bibliotekę kontrolera gier.

Przetwarzanie zdarzeń GameActivity

Jeśli Twoja gra używa GameActivity, przekierowuj zdarzenia GameActivityKeyEvent i GameActivityMotionEvent, wywołując metodę Paddleboat_processGameActivityKeyInputEvent lub Paddleboat_processGameActivityMotionInputEvent z kodu obsługi zdarzeń.

int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
                                                    const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
                                                       const size_t eventSize)
Parametr Opis
event Wskaźnik do struktury GameActivityKeyEvent lub GameActivityMotionEvent w zależności od tego, która funkcja jest wywoływana.
eventSize Rozmiar w bajtach struktury zdarzenia przekazany w parametrze event.

Obie funkcje zwracają wartość 0, jeśli zdarzenie zostało zignorowane, oraz wartość 1, jeśli zdarzenie zostało przetworzone i wykorzystane przez bibliotekę kontrolera gier.

GameActivity wymaga określenia aktywnej osi ruchu za pomocą funkcji GameActivityPointerAxes_enableAxis. Wywołanie Paddleboat_getActiveAxisMask zwraca maskę bitową aktualnie aktywnej osi ruchu używaną przez połączone kontrolery.

uint64_t Paddleboat_getActiveAxisMask()

Przykład obsługi tej funkcji znajdziesz w przykładowej bibliotece kontrolera gier, która korzysta z elementu GameActivity. Próbka sonduje maskę aktywnej osi i informuje GameActivity o użyciu nowej osi. Jest to zaimplementowane w funkcji 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;
        }
    }
}

Odczytywanie kontrolerów

Biblioteka kontrolerów gier korzysta z wartości indeksu w odniesieniu do konkretnego kontrolera. Prawidłowe wartości indeksu to od 0 do PADDLEBOAT_MAX_CONTROLLERS - 1. Funkcja Paddleboat_getControllerStatus określa stan określonego indeksu kontrolera.

Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
  const int32_t controllerIndex)

Istnieją 3 funkcje odczytu informacji z podłączonego kontrolera.

Nazwa kontrolera

Element Paddleboat_getControllerName function przyjmuje 2 parametry wejściowe: indeks kontrolera, rozmiar bufora i wskaźnik do bufora w celu przechowywania ciągu znaków z nazwą kontrolera. Jest on sformatowany pod postacią ciągu C w kodowaniu UTF-8. Nazwa urządzenia jest odczytywana wewnętrznie za pomocą InputDevice.getName().

Jeśli Paddleboat_getControllerName pobierze nazwę, zwraca PADDLEBOAT_NO_ERROR. W przeciwnym razie zwracany jest odpowiedni kod błędu.

Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
                                                  const size_t bufferSize,
                                                  char *controllerName);
Parametr Opis
controllerIndex Indeks kontrolera, który zainicjował wywołanie zwrotne. Będzie mieć wartość z zakresu od 0 do
. PADDLEBOAT_MAX_CONTROLLERS - 1
bufferSize Rozmiar w bajtach bufora przekazany przez controllerName. Ciąg nazwy zostanie obcięty w razie potrzeby, aby zmieścić się w buforze.
controllerName Wskaźnik do bufora bufferSize B w celu zapisania nazwy kontrolera. Nazwa zostanie zapisana jako ciąg znaków C z kodowaniem UTF-8.

Informacje o urządzeniu kontrolera

Element Paddleboat_getControllerInfo function przyjmuje 2 parametry wejściowe: indeks kontrolera i wskaźnik do struktury Paddleboat_Controller_Info.

Jeśli pole Paddleboat_Controller_Info zostało uzupełnione danymi, Paddleboat_getControllerInfo zwraca PADDLEBOAT_NO_ERROR. W przeciwnym razie zwracany jest odpowiedni kod błędu.

Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
  Paddleboat_Controller_Info *controllerInfo)

Struktura Paddleboat_Controller_Info zawiera informacje o kontrolerze dotyczące konkretnego urządzenia.

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;

Kilku elementów struktury jest wypełnianych na podstawie wartości pobranych z elementu InputDevice powiązanego z kontrolerem:

controllerNumber    -   InputDevice.getControllerNumber()
vendorId              - InputDevice.getVendorId()
productId             - InputDevice.getProductId()
deviceId              - InputDevice.getId()
  • Wartość stickFlat wskazuje zasięg środkowej płaskiej pozycji. Ta wartość przydaje się głównie do obliczania domyślnej środkowej „strefy” na urządzeniach samośrodkowych.
  • Wartość stickFuzz reprezentuje tolerancję błędów, czyli stopień, w jakim bieżąca wartość może odbiegać od rzeczywistej wartości z powodu ograniczeń czułości urządzenia i szumu.

Obie wartości są normalizowane do maksymalnej wartości na osi 1.0 w dowolnym wymiarze.

Element controllerFlags zawiera kombinację poszczególnych flag z maską bitową i kombinacji wartości wielobitowych.

Wykonanie funkcji logicznej AND z parametrem controllerFlags z wartością PADDLEBOAT_CONTROLLER_LAYOUT_MASK skutkuje wartością, którą można rzutować na wyliczenie Paddleboat_ControllerButtonLayout. Określa ona ikonę i układ przycisku używane przez kontroler.

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

Te stałe określają bity możliwości. Aby sprawdzić, czy kontroler obsługuje określoną funkcję, wykonaj funkcję logiczna AND odpowiadającą jej stałej wartości controllerFlags. Wartość inna niż 0 oznacza, że kontroler obsługuje daną możliwość.

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

Jeśli ten bit flagi jest ustawiony, kontroler ma zintegrowany touchpad. Po naciśnięciu touchpada kontroler ustawia bit PADDLEBOAT_BUTTON_TOUCHPAD w polu Paddleboat_Controller_Data.buttonsDown.

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

Jeśli ten bit flagi jest ustawiony, kontroler emuluje urządzenie wskaźnika. Element virtualPointer struktury Paddleboat_Controller_Data jest zapełniany bieżącymi współrzędnymi wirtualnego wskaźnika.

Dane administratora

Funkcja Paddleboat_getControllerData przyjmuje 2 parametry wejściowe: indeks kontrolera i wskaźnik do struktury Paddleboat_Controller_Data. Jeśli pole Paddleboat_Controller_Data zostało wypełnione danymi, Paddleboat_getControllerInfo zwraca wartość PADDLEBOAT_NO_ERROR. W przeciwnym razie zwracany jest odpowiedni kod błędu.

Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
  Paddleboat_Controller_Data *controllerData)

Struktura Paddleboat_Controller_Data zawiera bieżące kontrolne wartości wejściowe kontrolera.

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;

Zakresy wartości

Typ danych wejściowych Zakres wartości
Oś kciuka -1.01.0
Aktywatory 0.01.0
Wskaźniki wirtualne 0.0 na szerokość/wysokość okna (w pikselach)

Szczegóły struktury

Użytkownik struktury Opis
buttonsDown Tablica bitowa bitowa przycisku. Stałe maski bitowej przycisku są zdefiniowane w pliku nagłówka paddleboat.h i zaczynają się od PADDLEBOAT_BUTTON_.
timestamp. Sygnatura czasowa ostatniego zdarzenia wejściowego kontrolera. Sygnatura czasowa to mikrosekundy od początku epoki.
virtualPointer Lokalizacja wirtualnego wskaźnika. Tej formuły można użyć tylko wtedy, gdy w regule controllerFlags jest ustawiona flaga PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE. W przeciwnym razie ma wartość 0.0, 0.0.