Use as funções a seguir para adicionar compatibilidade com o controle de jogo usando a biblioteca Game Controller.
Inicializar e destruir a biblioteca Game Controller
Use a função Paddleboat_init
para inicializar a biblioteca Game Controller.
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
requer dois parâmetros:
- Um ponteiro para um
JNIEnv
anexado à linha de execução atual - Uma referência de objeto JNI
jobject
a uma classe derivada deContext
. QualquerContext
objeto de classe derivado é válido, incluindo, mas não se limitando aActivity
,NativeActivity
, ouGameActivity
.
Paddleboat_init
retornará
PADDLEBOAT_NO_ERROR
se a inicialização tiver êxito. Caso contrário, um código de erro adequado
será retornado.
Você pode usar Paddleboat_isInitialized
para verificar se a biblioteca Game
Controller foi inicializada. Ele retorna um valor
booleano. Se for verdadeiro, a API estará disponível para uso.
bool Paddleboat_isInitialized()
Antes de encerrar o aplicativo, use a função
Paddleboat_destroy
para encerrar a biblioteca Game Controller. A função usa um único
parâmetro, um ponteiro para um JNIEnv
anexado à linha de execução atual.
Paddleboat_init
pode ser chamado novamente após Paddleboat_destroy
.
void Paddleboat_destroy(JNIEnv *env)
Informar a biblioteca de eventos de ciclo de vida
A biblioteca Game Controller precisa ser informada dos eventos de
ciclo de vida da atividade
onStop
e
onStart
.
Chame as funções
Paddleboat_onStop
e
Paddleboat_onStart
do seu código de processamento de eventos de parada e início. As duas funções têm um
único parâmetro: um ponteiro para um JNIEnv
anexado à linha de execução atual.
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
Registrar ou remover um callback de status do controle
A biblioteca Game Controller usa um callback de status do controle para notificar um jogo quando um controle está conectado ou desconectado. Ela é compatível apenas com um callback de status de controle por vez.
- Para registrar um callback de status de controle ou substituir qualquer outro
registrado anteriormente por uma nova função de callback, chame a
função
Paddleboat_setControllerStatusCallback
. - Para remover qualquer callback registrado no momento, transmita
NULL
ounullptr
. - O parâmetro
userData
é um ponteiro opcional para dados definidos pelo usuário. A O parâmetrouserData
será transmitido para a função de callback. Esse ponteiro é mantido internamente até que seja alterado por uma chamada subsequente paraPaddleboat_setControllerStatusCallback
.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
A assinatura da função de callback é:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
Parâmetro | Descrição |
---|---|
controllerIndex
|
O índice do controle que iniciou o
callback. Será um valor entre 0 e PADDLEBOAT_MAX_CONTROLLERS - 1 |
controllerStatus
|
Valor de enumeração de
PADDLEBOAT_CONTROLLER_JUST_CONNECTED ou PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED . |
userData
|
Um ponteiro opcional (pode ser NULL) para dados
definidos pelo usuário especificados pela última chamada para
Paddleboat_setControllerStatusCallback . |
Chamar a função de atualização da biblioteca Game Controller
A função de atualização da biblioteca Game Controller,
Paddleboat_update
,
precisa ser chamada uma vez por frame do jogo, de preferência perto do início do frame.
A função usa um único parâmetro, um ponteiro para um JNIEnv
anexado ao
linha de execução atual.
void Paddleboat_update(JNIEnv *env)
Processar eventos
Ao receber eventos de entrada, seu jogo precisa encaminhá-los à biblioteca Game Controller para inspeção. Essa biblioteca avalia se um evento de entrada está associado a um dos dispositivos gerenciados. Os eventos de dispositivos gerenciados são processados e consumidos.
A biblioteca Game Controller é compatível com dois tipos de eventos de entrada:
AInputEvents
e
GameActivity
.
Processamento de AInputEvent
Seu jogo precisa encaminhar AInputEvents
chamando
Paddleboat_processInputEvent
do código de processamento de eventos.
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
Paddleboat_processInputEvent
retornará 0
se o evento for ignorado e 1
se ele tiver sido processado e consumido pela biblioteca Game Controller.
Processamento de eventos de GameActivity
Caso seu jogo use GameActivity
, encaminhe
GameActivityKeyEvent
e
GameActivityMotionEvent
de eventos chamando
Paddleboat_processGameActivityKeyInputEvent
ou
Paddleboat_processGameActivityMotionInputEvent
do código de manipulação de eventos.
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
Parâmetro | Descrição |
---|---|
event
|
Um ponteiro para uma estrutura GameActivityKeyEvent ou
GameActivityMotionEvent , dependendo
de qual função está sendo chamada. |
eventSize
|
O tamanho em bytes da estrutura do
evento transmitido no parâmetro event . |
Ambas as funções retornarão 0
se o evento tiver sido ignorado e 1
se tiver sido
processado e consumido pela biblioteca Game Controller.
GameActivity
requer que o eixo de movimento ativo seja especificado usando a
função GameActivityPointerAxes_enableAxis
. A chamada
Paddleboat_getActiveAxisMask
retorna um bitmask do eixo de movimento ativo atualmente usado pelos controles
conectados.
uint64_t Paddleboat_getActiveAxisMask()
Para ver um exemplo de como lidar com isso, consulte o exemplo da biblioteca Game Controller
que usa GameActivity
. A amostra pesquisa a máscara do eixo ativo e informa
GameActivity
quando um novo eixo é usado. Isso é implementado na
função 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;
}
}
}
Ler controles
A biblioteca Game Controller usa um valor de índice para se referir a um controle
específico. Os valores de índice válidos variam de 0
a
PADDLEBOAT_MAX_CONTROLLERS - 1
. A
Paddleboat_getControllerStatus
determina o status de um índice de controle especificado.
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
Há três funções para ler informações de um controle conectado.
- O
Paddleboat_getControllerName
função recupera o nome do dispositivo controlador. - O
Paddleboat_getControllerInfo
recupera dados sobre o próprio controle. - A função
Paddleboat_getControllerData
recupera o estado atual das entradas do controle.
Nome do controle
A Paddleboat_getControllerName function
usa dois parâmetros de entrada: um índice de controle, um tamanho de buffer e um ponteiro para um buffer para
armazenar a string de nome do controle. A string de nome é formatada como uma
string C usando a codificação UTF-8. O nome do dispositivo é coletado internamente
usando InputDevice.getName()
.
Se Paddleboat_getControllerName
recuperar o nome, retornará
PADDLEBOAT_NO_ERROR
. Caso contrário, um código de erro adequado será retornado.
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
Parâmetro | Descrição |
---|---|
controllerIndex
|
O índice do controle que iniciou o
callback. Será um valor entre 0 e PADDLEBOAT_MAX_CONTROLLERS - 1 |
bufferSize
|
Tamanho em bytes do buffer passado por
controllerName . A string do nome será
truncada, se necessário, para caber no buffer. |
controllerName
|
Um ponteiro para um buffer de bufferSize bytes
para armazenar o nome do controle. O nome será
armazenado como uma string C usando a codificação UTF-8. |
Informações do controle
A Paddleboat_getControllerInfo function
utiliza dois parâmetros de entrada: um
índice do controle e um ponteiro para uma estrutura Paddleboat_Controller_Info
.
Se Paddleboat_Controller_Info
tiver sido preenchido com os dados,
Paddleboat_getControllerInfo
retornará PADDLEBOAT_NO_ERROR
. Caso contrário,
será retornado um código de erro apropriado.
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
A estrutura Paddleboat_Controller_Info
contém informações específicas
sobre o controle.
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;
Vários membros da estrutura são preenchidos por valores retirados do
InputDevice
associado ao controle:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
- Um valor
stickFlat
representa a extensão de uma posição central. Esse valor é útil principalmente para calcular uma "zona inativa" padrão em dispositivos de autocentralização. - Um valor
stickFuzz
representa a tolerância a erros ou o quanto o valor atual pode ser diferente do valor real devido a limitações de ruído e sensibilidade do dispositivo.
Ambos os valores são normalizados para um valor máximo de eixo de 1.0
em qualquer dimensão.
O membro controllerFlags
contém uma combinação de sinalizações com bitmasks
individuais e valores de combinação de vários bits.
A execução de um AND
lógico de controllerFlags
com
PADDLEBOAT_CONTROLLER_LAYOUT_MASK
resulta em um valor que pode ser transmitido para a
enumeração Paddleboat_ControllerButtonLayout
. Essa enumeração especifica a iconografia
e o layout dos botões usados pelo controle.
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
};
As constantes a seguir definem bits de capacidade. Para determinar se um controle
é compatível com uma capacidade específica, execute um AND
lógico da constante correspondente
em relação a controllerFlags
. Um resultado diferente de zero significa que o recurso é
compatível com o controle.
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
Se esse bit de sinalização estiver definido, o controle trá um touchpad integrado. Se o
touchpad for pressionado, o controle definirá o bit PADDLEBOAT_BUTTON_TOUCHPAD
no
campo Paddleboat_Controller_Data.buttonsDown
.
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
Se esse bit de sinalização estiver definido, o controle emulará um dispositivo apontador. O
membro virtualPointer
da estrutura Paddleboat_Controller_Data
é
preenchido com as coordenadas atuais do ponteiro virtual.
Dados do controle
A função Paddleboat_getControllerData
usa dois parâmetros de entrada: um índice de controle e um ponteiro para uma estrutura Paddleboat_Controller_Data
. Se
Paddleboat_Controller_Data
foi preenchido com os dados.
Paddleboat_getControllerInfo
retorna PADDLEBOAT_NO_ERROR
. Caso contrário, um
o código de erro apropriado será retornado.
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
A estrutura Paddleboat_Controller_Data
contém os valores de entrada
atuais do controle.
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;
Intervalos de valor
Tipo de entrada | Intervalo de valor |
---|---|
Eixo do controle direcional analógico | de -1.0 a 1.0 |
Gatilhos | de 0.0 a 1.0 |
Ponteiros virtuais | 0.0 à largura/altura da janela (em pixels) |
Detalhes da estrutura
Membro da estrutura | Descrição |
---|---|
buttonsDown
|
Matriz de bitfield em bits por botão. As constantes de bitmask
do botão são definidas no arquivo de cabeçalho paddleboat.h
e começam com
PADDLEBOAT_BUTTON_ . |
timestamp.
|
O carimbo de data/hora do evento mais recente de entrada do controle. O carimbo de data/hora é exibido em microssegundos desde a época do relógio. |
virtualPointer
|
Localização do ponteiro virtual. Válido apenas se a sinalização
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
estiver definida em controllerFlags . Caso contrário, será
0.0, 0.0 . |