Menggunakan library Pengontrol Game

Gunakan fungsi berikut untuk menambahkan dukungan pengontrol game ke game Anda menggunakan library Pengontrol Game.

Menginisialisasi dan menghancurkan library Pengontrol Game

Gunakan fungsi Paddleboat_init untuk menginisialisasi library Pengontrol Game.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Paddleboat_init menggunakan dua parameter:

  • Pointer ke JNIEnv yang terpasang pada thread saat ini
  • jobject Referensi objek JNI ke class turunan Context. Yang Mana Pun Context objek class turunan valid, termasuk, tetapi tidak terbatas pada Activity, NativeActivity, atau GameActivity.

Paddleboat_init menampilkan PADDLEBOAT_NO_ERROR jika inisialisasi berhasil. Jika tidak, kode error yang sesuai akan ditampilkan.

Anda dapat menggunakan Paddleboat_isInitialized untuk memeriksa apakah library Pengontrol Game telah berhasil diinisialisasi atau belum. Tindakan ini akan menampilkan nilai boolean. Jika benar, API dapat digunakan.

bool Paddleboat_isInitialized()

Sebelum menghentikan aplikasi, gunakan fungsi Paddleboat_destroy untuk menonaktifkan library Pengontrol Game. Fungsi ini menggunakan satu parameter, pointer ke JNIEnv yang terpasang pada thread saat ini. Paddleboat_init dapat dipanggil lagi setelah Paddleboat_destroy.

void Paddleboat_destroy(JNIEnv *env)

Memberi tahu library tentang peristiwa siklus proses

Library Pengontrol Game harus mengetahui peristiwa siklus proses aktivitas onStop dan onStart. Panggil fungsi Paddleboat_onStop dan Paddleboat_onStart dari kode penanganan peristiwa henti dan mulai. Kedua fungsi tersebut menggunakan satu parameter: pointer ke JNIEnv yang terpasang pada thread saat ini.

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

Mendaftarkan atau menghapus callback status pengontrol

Library Pengontrol Game menggunakan callback status pengontrol untuk memberi tahu game saat pengontrol terhubung atau terputus. Hanya mendukung satu callback status pengontrol dalam satu waktu.

  • Untuk mendaftarkan callback status pengontrol atau mengganti callback yang sebelumnya telah terdaftar dengan fungsi callback baru, panggil fungsi Paddleboat_setControllerStatusCallback.
  • Untuk menghapus callback yang terdaftar saat ini, teruskan NULL atau nullptr.
  • Parameter userData adalah pointer opsional untuk data yang ditetapkan pengguna. Tujuan Parameter userData akan diteruskan ke fungsi callback. Pointer ini disimpan secara internal sampai diubah oleh panggilan berikutnya menjadi Paddleboat_setControllerStatusCallback.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
  statusCallback, void *userData)

Tanda tangan fungsi dari fungsi callback adalah:

typedef void (*Paddleboat_ControllerStatusCallback)(
  const int32_t controllerIndex,
  const Paddleboat_ControllerStatus controllerStatus,
  void *userData)
Parameter Deskripsi
controllerIndex Indeks pengontrol yang memulai callback. Akan berupa nilai antara 0 dan
PADDLEBOAT_MAX_CONTROLLERS - 1
controllerStatus Nilai Enum PADDLEBOAT_CONTROLLER_JUST_CONNECTED atau
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED.
userData Pointer opsional (mungkin NULL) ke data yang ditentukan pengguna dan yang ditetapkan oleh panggilan terakhir ke Paddleboat_setControllerStatusCallback.

Memanggil fungsi update library Pengontrol Game

Fungsi update library Pengontrol Game, Paddleboat_update, harus dipanggil satu kali per frame game, dan sebaiknya panggil di dekat bagian awal frame. Fungsi ini mengambil satu parameter, pointer ke JNIEnv yang dilampirkan ke rangkaian pesan saat ini.

void Paddleboat_update(JNIEnv *env)

Memproses peristiwa

Saat menerima peristiwa input, game Anda harus meneruskannya ke library Pengontrol Game untuk diperiksa. Library Pengontrol Game mengevaluasi apakah peristiwa input dikaitkan dengan salah satu perangkatnya yang terkelola atau tidak. Peristiwa dari perangkat terkelola akan diproses dan digunakan.

Library Pengontrol Game mendukung dua jenis peristiwa input: peristiwa input AInputEvents dan GameActivity.

Pemrosesan AInputEvent

Game Anda harus meneruskan AInputEvents dengan memanggil Paddleboat_processInputEvent dari kode penanganan peristiwa Anda.

int32_t Paddleboat_processInputEvent(const AInputEvent *event)

Paddleboat_processInputEvent akan menampilkan 0 jika peristiwa diabaikan dan 1 jika peristiwa diproses dan digunakan oleh library Pengontrol Game.

Pemrosesan peristiwa GameActivity

Jika game Anda menggunakan GameActivity, teruskan GameActivityKeyEvent dan Peristiwa GameActivityMotionEvent dengan memanggil Paddleboat_processGameActivityKeyInputEvent atau Paddleboat_processGameActivityMotionInputEvent dari kode penanganan peristiwa Anda.

int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
                                                    const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
                                                       const size_t eventSize)
Parameter Deskripsi
event Pointer ke struktur GameActivityKeyEvent atau GameActivityMotionEvent, bergantung pada fungsi yang dipanggil.
eventSize Ukuran struktur peristiwa dalam byte yang diteruskan dalam parameter event.

Kedua fungsi akan menampilkan 0 jika peristiwa diabaikan dan 1 jika peristiwa tersebut diproses dan digunakan oleh library Pengontrol Game.

GameActivity mengharuskan sumbu gerakan aktif ditetapkan menggunakan fungsi GameActivityPointerAxes_enableAxis. Panggilan Paddleboat_getActiveAxisMask menampilkan bitmask dari sumbu gerakan yang saat ini aktif dan digunakan oleh pengontrol yang terhubung.

uint64_t Paddleboat_getActiveAxisMask()

Untuk contoh cara menangani hal ini, lihat contoh library Pengontrol Game yang menggunakan GameActivity. Sampel melakukan polling mask sumbu aktif dan menginformasikan GameActivity saat sumbu baru digunakan. Ini akan diterapkan dalam fungsi 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;
        }
    }
}

Membaca pengontrol

Library Pengontrol Game menggunakan nilai indeks untuk merujuk pada pengontrol tertentu. Nilai indeks valid berkisar antara 0 hingga PADDLEBOAT_MAX_CONTROLLERS - 1. Tujuan Paddleboat_getControllerStatus menentukan status indeks pengontrol yang ditentukan.

Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
  const int32_t controllerIndex)

Ada tiga fungsi untuk membaca informasi dari pengontrol yang terhubung.

Nama pengontrol

Paddleboat_getControllerName function mengambil dua parameter input: indeks pengontrol, ukuran buffer, dan pointer ke buffer untuk menyimpan string nama pengontrol. String nama diformat sebagai string C menggunakan encoding UTF-8. Nama perangkat diperoleh secara internal menggunakan InputDevice.getName().

Jika Paddleboat_getControllerName berhasil mengambil nama tersebut, variabel akan menampilkan PADDLEBOAT_NO_ERROR, jika tidak, sebagai gantinya kode error yang sesuai akan ditampilkan.

Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
                                                  const size_t bufferSize,
                                                  char *controllerName);
Parameter Deskripsi
controllerIndex Indeks pengontrol yang memulai callback. Akan berupa nilai antara 0 dan
PADDLEBOAT_MAX_CONTROLLERS - 1
bufferSize Ukuran dalam byte buffer yang diteruskan oleh controllerName, string nama akan dipotong bila perlu agar sesuai dengan buffer.
controllerName Pointer ke buffer byte bufferSize untuk menyimpan nama pengontrol. Nama akan disimpan sebagai string C menggunakan encoding UTF-8.

Informasi perangkat pengontrol

Paddleboat_getControllerInfo function mengambil dua parameter input: indeks pengontrol dan pointer ke struktur Paddleboat_Controller_Info.

Jika Paddleboat_Controller_Info berhasil diisi dengan data, Paddleboat_getControllerInfo akan menampilkan PADDLEBOAT_NO_ERROR, jika tidak, sebagai gantinya kode error yang sesuai akan ditampilkan.

Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
  Paddleboat_Controller_Info *controllerInfo)

Struktur Paddleboat_Controller_Info berisi informasi khusus perangkat tentang pengontrol.

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;

Beberapa anggota struktur diisi dengan nilai yang diambil dari InputDevice yang terkait dengan pengontrol:

controllerNumber    -   InputDevice.getControllerNumber()
vendorId              - InputDevice.getVendorId()
productId             - InputDevice.getProductId()
deviceId              - InputDevice.getId()
  • Nilai stickFlat mewakili sejauh mana posisi datar tengah. Nilai ini sangat berguna untuk menghitung 'zona mati' di pusat default pada perangkat yang dapat terpusat secara otomatis.
  • Nilai stickFuzz menunjukkan toleransi error, atau seberapa jauh nilai saat ini mungkin menyimpang dari nilai sebenarnya karena keterbatasan derau dan sensitivitas perangkat.

Kedua nilai dinormalkan ke nilai sumbu maksimum 1.0 di kedua dimensi.

Anggota controllerFlags berisi kombinasi tanda bitmask individu dan nilai kombinasi multi-bit.

Melakukan AND logis dari controllerFlags dengan PADDLEBOAT_CONTROLLER_LAYOUT_MASK menghasilkan nilai yang dapat ditransmisikan ke enum Paddleboat_ControllerButtonLayout. Enum ini menentukan ikon dan tata letak tombol yang digunakan oleh pengontrol.

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

Konstanta berikut menentukan bit kemampuan. Untuk menentukan apakah pengontrol mendukung kemampuan tertentu, jalankan AND logis dari konstanta yang sesuai pada controllerFlags. Hasil bukan nol berarti kemampuan tersebut didukung oleh pengontrol.

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

Jika bit flag ini disetel, pengontrol memiliki touchpad terintegrasi. Jika touchpad ditekan, pengontrol akan menyetel bit PADDLEBOAT_BUTTON_TOUCHPAD dalam kolom Paddleboat_Controller_Data.buttonsDown.

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

Jika bit flag ini ditetapkan, pengontrol akan mengemulasi perangkat penunjuk. Anggota virtualPointer dari struktur Paddleboat_Controller_Data diisi dengan koordinat saat ini dari penunjuk virtual.

Data pengontrol

Fungsi Paddleboat_getControllerData mengambil dua parameter input: indeks pengontrol dan pointer ke struktur Paddleboat_Controller_Data. Jika Paddleboat_Controller_Data berhasil diisi dengan data, Paddleboat_getControllerInfo akan menampilkan PADDLEBOAT_NO_ERROR, jika tidak, kode error yang sesuai akan ditampilkan.

Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
  Paddleboat_Controller_Data *controllerData)

Struktur Paddleboat_Controller_Data berisi nilai input kontrol saat ini dari pengontrol.

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;

Rentang nilai

Jenis input Rentang nilai
Sumbu thumbstick -1.0 sampai 1.0
Pemicu 0.0 sampai 1.0
Pointer virtual 0.0 sampai lebar/tinggi jendela (dalam piksel)

Detail struktur

Anggota struktur Deskripsi
buttonsDown Array bitfield bit per tombol. Konstanta bitmask tombol ditentukan dalam file header paddleboat.h . dan dimulai dengan PADDLEBOAT_BUTTON_.
timestamp. Stempel waktu peristiwa input pengontrol terbaru. Stempel waktu dihitung dalam mikrodetik sejak epoch jam.
virtualPointer Lokasi pointer virtual. Hanya valid jika flag PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE disetel di controllerFlags, jika tidak, akan menjadi 0.0, 0.0.