Utilizza le seguenti funzioni per aggiungere il supporto del controller di gioco al tuo gioco utilizzando la libreria Game Controller.
Inizializzare e distruggere la libreria Game Controller
Utilizza la funzione Paddleboat_init
per inizializzare la libreria Game Controller.
Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)
Paddleboat_init
accetta due parametri:
- Un puntatore a un
JNIEnv
allegato al thread corrente - Un riferimento a un oggetto JNI
jobject
a una classe derivataContext
. Qualsiasi oggetto della classe derivataContext
è valido, inclusi, a titolo esemplificativo,Activity
,NativeActivity
oGameActivity
.
Paddleboat_init
restituisce
PADDLEBOAT_NO_ERROR
se l'inizializzazione è riuscita, altrimenti viene restituito un codice di errore appropriato.
Puoi utilizzare Paddleboat_isInitialized
per verificare se la libreria Game
Controller è stata inizializzata correttamente. Restituisce un valore booleano. Se è true, l'API è disponibile per l'uso.
bool Paddleboat_isInitialized()
Prima di terminare l'applicazione, utilizza la funzione
Paddleboat_destroy
per arrestare la libreria Game Controller. La funzione accetta un singolo
parametro, un puntatore a un JNIEnv
collegato al thread corrente.
Paddleboat_init
potrebbe essere richiamato dopo il giorno Paddleboat_destroy
.
void Paddleboat_destroy(JNIEnv *env)
Informare la libreria degli eventi del ciclo di vita
La libreria Game Controller deve essere informata del
ciclo di vita dell'attività
onStop
e degli
onStart
eventi.
Chiama le funzioni
Paddleboat_onStop
e
Paddleboat_onStart
dal codice di gestione degli eventi di arresto e avvio. Entrambe le funzioni richiedono un
unico parametro: un puntatore a un JNIEnv
collegato al thread corrente.
void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)
Registrare o rimuovere un callback dello stato del controller
La libreria Game Controller utilizza un callback dello stato del controller per notificare a un gioco quando un controller è connesso o disconnesso. Supporta una sola callback di stato del controller alla volta.
- Per registrare un callback di stato del controller o sostituire qualsiasi callback registrato in precedenza con una nuova funzione di callback, chiama la funzione
Paddleboat_setControllerStatusCallback
. - Per rimuovere qualsiasi callback attualmente registrato, passa
NULL
onullptr
. - Il parametro
userData
è un puntatore facoltativo ai dati definiti dall'utente. Il parametrouserData
verrà passato alla funzione di callback. Questo puntatore viene conservato internamente finché non viene modificato da una chiamata successiva aPaddleboat_setControllerStatusCallback
.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
statusCallback, void *userData)
La firma della funzione di callback è:
typedef void (*Paddleboat_ControllerStatusCallback)(
const int32_t controllerIndex,
const Paddleboat_ControllerStatus controllerStatus,
void *userData)
Parametro | Descrizione |
---|---|
controllerIndex
|
Indice del controller che ha avviato il
callback. Sarà un valore compreso tra 0 e PADDLEBOAT_MAX_CONTROLLERS - 1 |
controllerStatus
|
Valore enum di
PADDLEBOAT_CONTROLLER_JUST_CONNECTED o PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED . |
userData
|
Un puntatore facoltativo (può essere NULL) ai dati definiti dall'utente specificati dall'ultima chiamata a Paddleboat_setControllerStatusCallback . |
Chiamare la funzione di aggiornamento della libreria Game Controller
La funzione di aggiornamento della libreria Game Controller,
Paddleboat_update
, deve essere chiamata una volta per frame di gioco, preferibilmente all'inizio del frame.
La funzione accetta un singolo parametro, un puntatore a un JNIEnv
collegato al
thread corrente.
void Paddleboat_update(JNIEnv *env)
Elaborare eventi
Quando riceve eventi di input, il gioco deve inoltrarli alla libreria Game Controller per l'ispezione. La libreria Game Controller valuta se un evento di input è associato a uno dei dispositivi gestiti. Gli eventi provenienti dai dispositivi gestiti vengono elaborati e utilizzati.
La libreria Game Controller supporta due tipi di eventi di input:
AInputEvents
e
GameActivity
.
Elaborazione di AInputEvent
Il gioco deve inoltrare AInputEvents
chiamando
Paddleboat_processInputEvent
dal codice di gestione degli eventi.
int32_t Paddleboat_processInputEvent(const AInputEvent *event)
Paddleboat_processInputEvent
restituirà 0
se l'evento è stato ignorato e 1
se l'evento è stato elaborato e utilizzato dalla libreria Game Controller.
Elaborazione eventi GameActivity
Se il tuo gioco utilizza GameActivity
, inoltra gli eventi
GameActivityKeyEvent
e
GameActivityMotionEvent
chiamando
Paddleboat_processGameActivityKeyInputEvent
o
Paddleboat_processGameActivityMotionInputEvent
dal codice di gestione degli eventi.
int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
const size_t eventSize)
Parametro | Descrizione |
---|---|
event
|
Un puntatore a una struttura GameActivityKeyEvent o GameActivityMotionEvent , a seconda della funzione chiamata. |
eventSize
|
Le dimensioni in byte della struttura dell'evento
trasmessa nel parametro event . |
Entrambe le funzioni restituiranno 0
se l'evento è stato ignorato e 1
se l'evento è stato
elaborato e utilizzato dalla libreria Game Controller.
GameActivity
richiede che l'asse di movimento attivo venga specificato utilizzando la funzione
GameActivityPointerAxes_enableAxis
. La chiamata
Paddleboat_getActiveAxisMask
restituisce una maschera di bit dell'asse di movimento attualmente attivo utilizzato dai controller
connessi.
uint64_t Paddleboat_getActiveAxisMask()
Per un esempio di come gestire questo problema, consulta l'esempio della libreria Game Controller
che utilizza GameActivity
. Il campione esegue il polling della maschera dell'asse attivo e informa
GameActivity
quando vengono utilizzati nuovi assi. Questa operazione viene implementata nella funzione
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;
}
}
}
Lettura controller
La libreria Game Controller utilizza un valore di indice per fare riferimento a un controller specifico. I valori di indice validi sono compresi tra 0
e
PADDLEBOAT_MAX_CONTROLLERS - 1
. La funzione
Paddleboat_getControllerStatus
determina lo stato di un indice del controller specificato.
Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
const int32_t controllerIndex)
Esistono tre funzioni per leggere le informazioni da un controller connesso.
- La funzione
Paddleboat_getControllerName
recupera il nome del dispositivo di controllo. - La funzione
Paddleboat_getControllerInfo
recupera i dati sul dispositivo di controllo stesso. - La funzione
Paddleboat_getControllerData
recupera lo stato attuale degli input del controller.
Nome del controller
La funzione Paddleboat_getControllerName function
accetta due parametri di input: un indice del controller, una dimensione del buffer e un puntatore a
un buffer per memorizzare la stringa del nome del controller. La stringa del nome è formattata come una
stringa C utilizzando la codifica UTF-8. Il nome del dispositivo viene ottenuto internamente
utilizzando InputDevice.getName()
.
Se Paddleboat_getControllerName
recupera correttamente il nome, restituisce
PADDLEBOAT_NO_ERROR
, altrimenti viene restituito un codice di errore appropriato.
Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
const size_t bufferSize,
char *controllerName);
Parametro | Descrizione |
---|---|
controllerIndex
|
Indice del controller che ha avviato il
callback. Sarà un valore compreso tra 0 e PADDLEBOAT_MAX_CONTROLLERS - 1 |
bufferSize
|
Dimensione in byte del buffer passato da
controllerName , la stringa del nome verrà
troncata se necessario per adattarsi al buffer. |
controllerName
|
Un puntatore a un buffer di bufferSize byte
per memorizzare il nome del controller. Il nome verrà
memorizzato come stringa C utilizzando la codifica UTF-8. |
Informazioni sul dispositivo controller
Paddleboat_getControllerInfo function
accetta due parametri di input: un indice del controller e un puntatore a una struttura Paddleboat_Controller_Info
.
Se Paddleboat_Controller_Info
è stato compilato correttamente con i dati,
Paddleboat_getControllerInfo
restituisce PADDLEBOAT_NO_ERROR
, altrimenti viene restituito un
codice di errore appropriato.
Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
Paddleboat_Controller_Info *controllerInfo)
La struttura Paddleboat_Controller_Info
contiene informazioni specifiche del dispositivo
sul controller.
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;
Diversi membri della struttura vengono compilati con valori presi dal
InputDevice
associato al
controller:
controllerNumber - InputDevice.getControllerNumber()
vendorId - InputDevice.getVendorId()
productId - InputDevice.getProductId()
deviceId - InputDevice.getId()
- Un valore
stickFlat
rappresenta l'estensione di una posizione centrale piatta. Questo valore è utile principalmente per calcolare una "zona morta" centrale predefinita sui dispositivi autocentranti. - Un valore
stickFuzz
rappresenta la tolleranza all'errore o la distanza che il valore attuale può discostarsi dal valore effettivo a causa di limitazioni di rumore e sensibilità del dispositivo.
Entrambi i valori sono normalizzati a un valore massimo dell'asse di 1.0
in entrambe le dimensioni.
Il membro controllerFlags
contiene una combinazione di flag con maschera di bit individuali e valori di combinazione di più bit.
L'esecuzione di un'operazione logica AND
di controllerFlags
con
PADDLEBOAT_CONTROLLER_LAYOUT_MASK
restituisce un valore che può essere convertito nell'enumerazione
Paddleboat_ControllerButtonLayout
. Questo enum specifica l'iconografia e il layout dei pulsanti utilizzati dal controller.
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
};
Le seguenti costanti definiscono i bit di funzionalità. Per determinare se un controller
supporta una funzionalità specifica, esegui un'operazione logica AND
della costante
corrispondente rispetto a controllerFlags
. Un risultato diverso da zero indica che la funzionalità è
supportata dal controller.
PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD
Se questo bit di flag è impostato, il controller ha un touchpad integrato. Se il
touchpad viene premuto, il controller imposta il bit PADDLEBOAT_BUTTON_TOUCHPAD
nel
campo Paddleboat_Controller_Data.buttonsDown
.
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
Se questo bit di flag è impostato, il controller emula un dispositivo di puntamento. Il membro
virtualPointer
della struttura Paddleboat_Controller_Data
è
compilato con le coordinate attuali del puntatore virtuale.
Dati del controller
La funzione Paddleboat_getControllerData
accetta due parametri di input: un
indice del controller e un puntatore a una struttura Paddleboat_Controller_Data
. Se
Paddleboat_Controller_Data
viene compilato correttamente con i dati,
Paddleboat_getControllerInfo
restituisce PADDLEBOAT_NO_ERROR
, altrimenti viene restituito un
codice di errore appropriato.
Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
Paddleboat_Controller_Data *controllerData)
La struttura Paddleboat_Controller_Data
contiene i valori di input di controllo attuali del controller.
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;
Intervalli di valori
Tipo di input | Intervallo di valori |
---|---|
Asse della levetta | Da -1.0 a 1.0 |
Attivatori | Da 0.0 a 1.0 |
Puntatori virtuali | Da 0.0 alla larghezza/altezza della finestra (in pixel) |
Dettagli della struttura
Membro della struttura | Descrizione |
---|---|
buttonsDown
|
Array di campi di bit per pulsante. Le costanti della maschera di bit dei pulsanti sono definite nel file di intestazione paddleboat.h e iniziano con PADDLEBOAT_BUTTON_ . |
timestamp.
|
Timestamp dell'evento di input del controller più recente. Il timestamp è in microsecondi dall'epoca dell'orologio. |
virtualPointer
|
Posizione del puntatore virtuale. Valido solo se il flag
PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE
è impostato in controllerFlags , altrimenti sarà
0.0, 0.0 . |