mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-05 07:32:46 +02:00
Add support for joystick motion sensors on Android
This commit is contained in:
@@ -312,10 +312,15 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jint hat_id, jint x, jint y);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jint sensor_type, jlong sensor_timestamp, jfloat x, jfloat y, jfloat z);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led);
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats,
|
||||
jboolean can_rumble, jboolean has_rgb_led, jboolean has_accelerometer, jboolean has_gyroscope);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
@@ -335,7 +340,8 @@ static JNINativeMethod SDLControllerManager_tab[] = {
|
||||
{ "onNativePadUp", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },
|
||||
{ "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },
|
||||
{ "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) },
|
||||
{ "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIIIIIZZ)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
|
||||
{ "onNativeJoySensor", "(IIJFFF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor) },
|
||||
{ "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIIIIIZZZZ)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
|
||||
{ "nativeRemoveJoystick", "(I)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) },
|
||||
{ "nativeAddHaptic", "(ILjava/lang/String;)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) },
|
||||
{ "nativeRemoveHaptic", "(I)V", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) }
|
||||
@@ -408,6 +414,7 @@ static jclass mControllerManagerClass;
|
||||
// method signatures
|
||||
static jmethodID midPollInputDevices;
|
||||
static jmethodID midJoystickSetLED;
|
||||
static jmethodID midJoystickSetSensorsEnabled;
|
||||
static jmethodID midPollHapticDevices;
|
||||
static jmethodID midHapticRun;
|
||||
static jmethodID midHapticRumble;
|
||||
@@ -756,6 +763,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env
|
||||
"pollInputDevices", "()V");
|
||||
midJoystickSetLED = (*env)->GetStaticMethodID(env, mControllerManagerClass,
|
||||
"joystickSetLED", "(IIII)V");
|
||||
midJoystickSetSensorsEnabled = (*env)->GetStaticMethodID(env, mControllerManagerClass,
|
||||
"joystickSetSensorsEnabled", "(IZ)V");
|
||||
midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass,
|
||||
"pollHapticDevices", "()V");
|
||||
midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass,
|
||||
@@ -765,7 +774,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env
|
||||
midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass,
|
||||
"hapticStop", "(I)V");
|
||||
|
||||
if (!midPollInputDevices || !midJoystickSetLED || !midPollHapticDevices || !midHapticRun || !midHapticRumble || !midHapticStop) {
|
||||
if (!midPollInputDevices || !midJoystickSetLED || !midJoystickSetSensorsEnabled || !midPollHapticDevices || !midHapticRun || !midHapticRumble || !midHapticStop) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?");
|
||||
}
|
||||
|
||||
@@ -1191,17 +1200,29 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
|
||||
#endif // SDL_JOYSTICK_ANDROID
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoySensor)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jint sensor_type, jlong sensor_timestamp, jfloat x, jfloat y, jfloat z)
|
||||
{
|
||||
#ifdef SDL_JOYSTICK_ANDROID
|
||||
// In Java there's no Uint64 type, so pass Sint64 as if it was Uint64.
|
||||
Android_OnJoySensor(device_id, sensor_type, sensor_timestamp, x, y, z);
|
||||
#endif // SDL_JOYSTICK_ANDROID
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jstring device_name, jstring device_desc,
|
||||
jint vendor_id, jint product_id,
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led)
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats, jboolean can_rumble, jboolean has_rgb_led,
|
||||
jboolean has_accelerometer, jboolean has_gyroscope)
|
||||
{
|
||||
#ifdef SDL_JOYSTICK_ANDROID
|
||||
const char *name = (*env)->GetStringUTFChars(env, device_name, NULL);
|
||||
const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL);
|
||||
|
||||
Android_AddJoystick(device_id, name, desc, vendor_id, product_id, button_mask, naxes, axis_mask, nhats, can_rumble, has_rgb_led);
|
||||
Android_AddJoystick(device_id, name, desc, vendor_id, product_id, button_mask, naxes, axis_mask, nhats,
|
||||
can_rumble, has_rgb_led, has_accelerometer, has_gyroscope);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, device_name, name);
|
||||
(*env)->ReleaseStringUTFChars(env, device_desc, desc);
|
||||
@@ -2626,6 +2647,12 @@ void Android_JNI_JoystickSetLED(int device_id, int red, int green, int blue)
|
||||
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midJoystickSetLED, device_id, red, green, blue);
|
||||
}
|
||||
|
||||
void Android_JNI_JoystickSetSensorsEnabled(int device_id, bool enabled)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midJoystickSetSensorsEnabled, device_id, (enabled == 1));
|
||||
}
|
||||
|
||||
void Android_JNI_PollHapticDevices(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
|
||||
@@ -105,6 +105,7 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco
|
||||
// Joystick support
|
||||
void Android_JNI_PollInputDevices(void);
|
||||
void Android_JNI_JoystickSetLED(int device_id, int red, int green, int blue);
|
||||
void Android_JNI_JoystickSetSensorsEnabled(int device_id, bool enabled);
|
||||
|
||||
// Haptic support
|
||||
void Android_JNI_PollHapticDevices(void);
|
||||
|
||||
@@ -306,7 +306,37 @@ bool Android_OnHat(int device_id, int hat_id, int x, int y)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble, bool has_rgb_led)
|
||||
void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp, float x, float y, float z)
|
||||
{
|
||||
Uint64 timestamp = SDL_GetTicksNS();
|
||||
SDL_joylist_item *item;
|
||||
SDL_SensorType sensor;
|
||||
float data[3];
|
||||
|
||||
if (sensor_type == 1) { // Sensor.TYPE_ACCELEROMETER
|
||||
sensor = SDL_SENSOR_ACCEL;
|
||||
} else if (sensor_type == 4) { // Sensor.TYPE_GYROSCOPE
|
||||
sensor = SDL_SENSOR_GYRO;
|
||||
} else {
|
||||
// Unsupported sensor
|
||||
return;
|
||||
}
|
||||
|
||||
// The axes of sensor events and their signs are the same as SDL's, so no conversion required
|
||||
data[0] = x;
|
||||
data[1] = y;
|
||||
data[2] = z;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
item = JoystickByDeviceId(device_id);
|
||||
if (item && item->joystick) {
|
||||
SDL_SendJoystickSensor(timestamp, item->joystick, sensor, sensor_timestamp, data, 3);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
}
|
||||
|
||||
void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats,
|
||||
bool can_rumble, bool has_rgb_led, bool has_accelerometer, bool has_gyroscope)
|
||||
{
|
||||
SDL_joylist_item *item;
|
||||
SDL_GUID guid;
|
||||
@@ -382,6 +412,8 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int
|
||||
item->nhats = nhats;
|
||||
item->can_rumble = can_rumble;
|
||||
item->has_rgb_led = has_rgb_led;
|
||||
item->has_accelerometer = has_accelerometer;
|
||||
item->has_gyroscope = has_accelerometer;
|
||||
item->device_instance = SDL_GetNextObjectID();
|
||||
if (!SDL_joylist_tail) {
|
||||
SDL_joylist = SDL_joylist_tail = item;
|
||||
@@ -587,6 +619,13 @@ static bool ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, true);
|
||||
}
|
||||
|
||||
if (item->has_accelerometer) {
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f);
|
||||
}
|
||||
if (item->has_gyroscope) {
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -631,7 +670,15 @@ static bool ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data,
|
||||
|
||||
static bool ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
|
||||
if (!item) {
|
||||
return SDL_SetError("SetSensorsEnabled failed, device disconnected");
|
||||
}
|
||||
if (!item->has_accelerometer && !item->has_gyroscope) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
Android_JNI_JoystickSetSensorsEnabled(item->device_id, enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ANDROID_JoystickUpdate(SDL_Joystick *joystick)
|
||||
|
||||
@@ -32,7 +32,9 @@ extern bool Android_OnPadDown(int device_id, int keycode);
|
||||
extern bool Android_OnPadUp(int device_id, int keycode);
|
||||
extern bool Android_OnJoy(int device_id, int axisnum, float value);
|
||||
extern bool Android_OnHat(int device_id, int hat_id, int x, int y);
|
||||
extern void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats, bool can_rumble, bool has_rgb_led);
|
||||
extern void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp, float x, float y, float z);
|
||||
extern void Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, int button_mask, int naxes, int axis_mask, int nhats,
|
||||
bool can_rumble, bool has_rgb_led, bool has_accelerometer, bool has_gyroscope);
|
||||
extern void Android_RemoveJoystick(int device_id);
|
||||
|
||||
// A linked list of available joysticks
|
||||
@@ -47,6 +49,8 @@ typedef struct SDL_joylist_item
|
||||
int dpad_state;
|
||||
bool can_rumble;
|
||||
bool has_rgb_led;
|
||||
bool has_accelerometer;
|
||||
bool has_gyroscope;
|
||||
|
||||
struct SDL_joylist_item *next;
|
||||
} SDL_joylist_item;
|
||||
|
||||
Reference in New Issue
Block a user