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 JNIEnvanexado à linha de execução atual
- Uma referência de objeto JNI jobjecta uma classe derivada deContext. Todos os objetos de classe derivadaContextsão válidos, incluindo, entre outros:Activity,NativeActivityouGameActivity.
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 poderá ser chamado novamente depois de 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 NULLounullptr.
- O parâmetro userDataé um ponteiro opcional para dados definidos pelo usuário. O parâmetrouserDataserá 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 0ePADDLEBOAT_MAX_CONTROLLERS - 1 | 
| controllerStatus | Valor de enumeração de PADDLEBOAT_CONTROLLER_JUST_CONNECTEDouPADDLEBOAT_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 à
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
Se o jogo usar GameActivity, encaminhe
os eventos GameActivityKeyEvent e
GameActivityMotionEvent chamando
Paddleboat_processGameActivityKeyInputEvent
ou
Paddleboat_processGameActivityMotionInputEvent
do seu 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 GameActivityKeyEventouGameActivityMotionEvent, 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 o 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 função 
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.
- A função Paddleboat_getControllerNamerecupera o nome do controle.
- A função Paddleboat_getControllerInforecupera dados sobre o próprio controle.
- A função Paddleboat_getControllerDatarecupera 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 0ePADDLEBOAT_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 bufferSizebytes
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 stickFlatrepresenta 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 stickFuzzrepresenta 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 for preenchido com os dados,
Paddleboat_getControllerInfo retornará PADDLEBOAT_NO_ERROR. Caso contrário, um
código de erro adequado 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.0a1.0 | 
| Gatilhos | de 0.0a1.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_MOUSEestiver definida emcontrollerFlags. Caso contrário, será0.0, 0.0. | 
