Используйте следующие функции для добавления поддержки игрового контроллера в вашу игру с помощью библиотеки игровых контроллеров.
Инициализируйте и удалите библиотеку игрового контроллера
Используйте функцию 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
. Функция возвращает логическое значение. Если значение равно 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)
Регистрация или удаление обратного вызова статуса контроллера
Библиотека игровых контроллеров использует функцию обратного вызова статуса контроллера для уведомления игры о его подключении или отключении. Она поддерживает только одну функцию обратного вызова статуса контроллера одновременно.
- Чтобы зарегистрировать обратный вызов состояния контроллера или заменить любой ранее зарегистрированный обратный вызов новой функцией обратного вызова, вызовите функцию
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
.
Обработка событий ввода
Ваша игра должна пересылать 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()
Пример решения этой проблемы можно найти в примере библиотеки Game Controller, использующей 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
извлекает имя устройства контроллера. - Функция
Paddleboat_getControllerInfo
извлекает данные о самом устройстве контроллера. - Функция
Paddleboat_getControllerData
извлекает текущее состояние входов контроллера.
Имя контроллера
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 . |