From e69c559d966d2840769e45abcd067ecd4cc45e3b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 30 Dec 2013 23:54:24 -0600 Subject: [PATCH] Oops, forgot the actual code... --- jni/gamepad_jni/gamepad_jni.c | 108 ++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 jni/gamepad_jni/gamepad_jni.c diff --git a/jni/gamepad_jni/gamepad_jni.c b/jni/gamepad_jni/gamepad_jni.c new file mode 100644 index 0000000..c28f3eb --- /dev/null +++ b/jni/gamepad_jni/gamepad_jni.c @@ -0,0 +1,108 @@ +#include +#include + +#include "Gamepad.h" + +static JavaVM *jvm; +static jclass nativeGamepadClass; +static jmethodID jdeviceAttached; +static jmethodID jdeviceRemoved; +static jmethodID jbuttonDown; +static jmethodID jbuttonUp; +static jmethodID jaxisMove; + +static JNIEnv *getThreadEnv(void) { + JNIEnv *env; + (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6); + return env; +} + +static void invokeJavaCallback(jmethodID method, ...) { + JNIEnv *env = getThreadEnv(); + va_list args; + va_start(args, method); + (*env)->CallStaticVoidMethodV(env, nativeGamepadClass, method, args); + va_end(args); +} + +static void deviceAttachCallback(struct Gamepad_device * device, void * context) { + invokeJavaCallback(jdeviceAttached, device->deviceID, device->numButtons, device->numAxes); +} + +static void deviceRemoveCallback(struct Gamepad_device * device, void * context) { + invokeJavaCallback(jdeviceRemoved, device->deviceID); +} + +static void buttonDownCallback(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) { + invokeJavaCallback(jbuttonDown, device->deviceID, buttonID); +} + +static void buttonUpCallback(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) { + invokeJavaCallback(jbuttonUp, device->deviceID, buttonID); +} + +static void axisMoveCallback(struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp, void * context) { + invokeJavaCallback(jaxisMove, device->deviceID, axisID, value, lastValue); +} + +// This function must be called first +JNIEXPORT void JNICALL +Java_com_limelight_input_gamepad_NativeGamepad_init(JNIEnv *env, jobject this) { + Gamepad_deviceAttachFunc(deviceAttachCallback, NULL); + Gamepad_deviceRemoveFunc(deviceRemoveCallback, NULL); + Gamepad_buttonDownFunc(buttonDownCallback, NULL); + Gamepad_buttonUpFunc(buttonUpCallback, NULL); + Gamepad_axisMoveFunc(axisMoveCallback, NULL); + + Gamepad_init(); +} + +// This function must be called last +JNIEXPORT void JNICALL +Java_com_limelight_input_gamepad_NativeGamepad_shutdown(JNIEnv *env, jobject this) { + Gamepad_shutdown(); + + // Remove the class reference + (*env)->DeleteGlobalRef(env, nativeGamepadClass); +} + +// This returns the number of connected devices +JNIEXPORT jint JNICALL +Java_com_limelight_input_gamepad_NativeGamepad_numDevices(JNIEnv *env, jobject this) { + return Gamepad_numDevices(); +} + +// This triggers device detection +JNIEXPORT void JNICALL +Java_com_limelight_input_gamepad_NativeGamepad_detectDevices(JNIEnv *env, jobject this) { + Gamepad_detectDevices(); +} + +// This polls for events and calls the appropriate callbacks +JNIEXPORT jint JNICALL +Java_com_limelight_input_gamepad_NativeGamepad_processEvents(JNIEnv *env, jobject this) { + Gamepad_processEvents(); +} + +// This is called when the library is first loaded +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *pjvm, void *reserved) { + JNIEnv *env; + + // This has to be saved before getThreadEnv() can be called + jvm = pjvm; + + env = getThreadEnv(); + + // We use a global reference to keep the class loaded + nativeGamepadClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/limelight/input/gamepad/NativeGamepad")); + + // These method IDs are only valid as long as the NativeGamepad class is loaded + jdeviceAttached = (*env)->GetStaticMethodID(env, nativeGamepadClass, "deviceAttachCallback", "(III)V"); + jdeviceRemoved = (*env)->GetStaticMethodID(env, nativeGamepadClass, "deviceRemoveCallback", "(I)V"); + jbuttonDown = (*env)->GetStaticMethodID(env, nativeGamepadClass, "buttonDownCallback", "(II)V"); + jbuttonUp = (*env)->GetStaticMethodID(env, nativeGamepadClass, "buttonUpCallback", "(II)V"); + jaxisMove = (*env)->GetStaticMethodID(env, nativeGamepadClass, "axisMovedCallback", "(IIFF)V"); + + return JNI_VERSION_1_6; +}