Используйте библиотеку игрового контроллера

Используйте следующие функции, чтобы добавить поддержку игрового контроллера в вашу игру с помощью библиотеки игрового контроллера.

Инициализируйте и уничтожьте библиотеку игрового контроллера.

Используйте функцию Paddleboat_init для инициализации библиотеки игрового контроллера.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Paddleboat_init принимает два параметра:

  • Указатель на JNIEnv , прикрепленный к текущему потоку.
  • Ссылка на объект JNI jobject задания на производный Context класс. Любой объект класса, производного от Context , является допустимым, включая, помимо прочего, Activity , NativeActivity или GameActivity .

Paddleboat_init возвращает PADDLEBOAT_NO_ERROR если инициализация прошла успешно, в противном случае возвращается соответствующий код ошибки.

Вы можете использовать Paddleboat_isInitialized чтобы проверить, была ли успешно инициализирована библиотека игрового контроллера. Он возвращает логическое значение. Если это правда, 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)

Зарегистрируйте или удалите обратный вызов состояния контроллера

Библиотека игрового контроллера использует обратный вызов состояния контроллера, чтобы уведомить игру, когда контроллер подключен или отключен. Он поддерживает только один обратный вызов состояния контроллера одновременно.

  • Чтобы зарегистрировать обратный вызов состояния контроллера или заменить любой ранее зарегистрированный обратный вызов новой функцией обратного вызова, вызовите функцию 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 Значение перечисления PADDLEBOAT_CONTROLLER_JUST_CONNECTED или
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED .
userData Необязательный указатель (может быть NULL) на определенные пользователем данные, указанные при последнем вызове Paddleboat_setControllerStatusCallback .

Вызов функции обновления библиотеки игрового контроллера

Функцию обновления библиотеки игрового контроллера Paddleboat_update следует вызывать один раз для каждого игрового кадра, желательно в начале кадра. Функция принимает единственный параметр — указатель на JNIEnv прикрепленный к текущему потоку.

void Paddleboat_update(JNIEnv *env)

События процесса

При получении входных событий ваша игра должна пересылать их в библиотеку игрового контроллера для проверки. Библиотека игрового контроллера оценивает, связано ли входное событие с одним из управляемых ею устройств. События от управляемых устройств обрабатываются и потребляются.

Библиотека игрового контроллера поддерживает два типа входных событий: входные события 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;
        }
    }
}

Чтение контроллеров

Библиотека игрового контроллера использует значение индекса для ссылки на конкретный контроллер. Допустимые значения индекса находятся в диапазоне от 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 содержит комбинацию отдельных флагов с битовой маской и значений многобитовых комбинаций.

Выполнение логического AND controllerFlags с PADDLEBOAT_CONTROLLER_LAYOUT_MASK приводит к значению, которое можно привести к перечислению Paddleboat_ControllerButtonLayout . Это перечисление определяет значок и макет кнопки, используемый контроллером.

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 Побитовый массив битовых полей. Константы битовой маски кнопок определены в файле Paddleboat.h . заголовочный файл и начать с PADDLEBOAT_BUTTON_ .
timestamp. Временная метка самого последнего события ввода контроллера. Временная метка равна микросекундам с момента начала работы часов.
virtualPointer Местоположение виртуального указателя. Действует только в том случае, если в controllerFlags установлен флаг PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE , в противном случае будет 0.0, 0.0 .