aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/DX8/src/native/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/DX8/src/native/input.cpp')
-rw-r--r--plugins/DX8/src/native/input.cpp888
1 files changed, 888 insertions, 0 deletions
diff --git a/plugins/DX8/src/native/input.cpp b/plugins/DX8/src/native/input.cpp
new file mode 100644
index 0000000..ccfda2f
--- /dev/null
+++ b/plugins/DX8/src/native/input.cpp
@@ -0,0 +1,888 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#ifndef WIN32
+ #error This is a Windows-only file
+#endif
+
+// hard define as DX7
+//#define DIRECTINPUT_VERSION 0x0800
+#include <windows.h>
+#include <jni.h>
+#include <dinput.h>
+
+
+/*
+ ******************************************************************************
+ * Global variables
+ ******************************************************************************
+ */
+jclass CLASS_AxisIdentifier = NULL;
+jclass CLASS_ButtonIdentifier = NULL;
+jclass CLASS_DirectInputEnvironmentPlugin = NULL;
+jclass CLASS_DirectInputDevice = NULL;
+jclass CLASS_DirectInputKeyboard = NULL;
+jclass CLASS_DirectInputMouse = NULL;
+jmethodID MID_AddDevice = NULL;
+jmethodID MID_AddAxis = NULL;
+jmethodID MID_RenameKey = NULL;
+jmethodID MID_RenameAxis = NULL;
+jfieldID FID_X = NULL;
+jfieldID FID_Y = NULL;
+jfieldID FID_Z = NULL;
+jfieldID FID_RX = NULL;
+jfieldID FID_RY = NULL;
+jfieldID FID_RZ = NULL;
+jfieldID FID_Slider = NULL;
+jfieldID FID_Button = NULL;
+jfieldID FID_POV = NULL;
+jfieldID FID_Left = NULL;
+jfieldID FID_Right = NULL;
+jfieldID FID_Middle = NULL;
+
+const char* FD_AxisIdentifier = "Lnet/java/games/input/Axis$Identifier;";
+const char* FD_ButtonIdentifier = "Lnet/java/games/input/Mouse$ButtonID;";
+// Dummy input window. This is needed because DirectX evidently needs a window
+// to do anything, such as setting the cooperative level for a device.
+const TCHAR* DUMMY_WINDOW_NAME = "InputControllerWindow";
+HWND hwndDummy = NULL;
+// Buffer size
+const DWORD BUFFER_SIZE = 16;
+
+// Class for handing device data to the callback for EnumDevices
+class DeviceParamData {
+public:
+ DeviceParamData(LPDIRECTINPUT8 lpdi, JNIEnv* e, jobject o, jobject l) :
+ lpDirectInput(lpdi), env(e), obj(o), list(l)
+ {
+ }
+ LPDIRECTINPUT8 lpDirectInput;
+ JNIEnv* env;
+ jobject obj;
+ jobject list;
+};
+
+// Class for handing device data to the callback for EnumObjects
+class ObjectParamData {
+public:
+ ObjectParamData(LPDIRECTINPUTDEVICE8 lpDev, JNIEnv* e, jobject o,
+ jobject l) :
+ lpDevice(lpDev), env(e), obj(o), list(l)
+ {
+ }
+ LPDIRECTINPUTDEVICE8 lpDevice;
+ JNIEnv* env;
+ jobject obj;
+ jobject list;
+};
+
+void PrintOutput(TCHAR* tszMessage) {
+ printf("%s\n", tszMessage);
+}
+
+void PrintDIError(TCHAR* tszOutput, HRESULT res) {
+ TCHAR tszMessage[256];
+#define CHECK_RESULT(r) case r: \
+sprintf(tszMessage, "%s : %s", tszOutput, #r); \
+break;
+ switch (res) {
+ CHECK_RESULT(DI_OK)
+ CHECK_RESULT(DI_NOTATTACHED)
+ CHECK_RESULT(DI_POLLEDDEVICE)
+ CHECK_RESULT(DI_DOWNLOADSKIPPED)
+ CHECK_RESULT(DI_EFFECTRESTARTED)
+ CHECK_RESULT(DI_TRUNCATED)
+ CHECK_RESULT(DI_TRUNCATEDANDRESTARTED)
+ CHECK_RESULT(DIERR_OLDDIRECTINPUTVERSION)
+ CHECK_RESULT(DIERR_BETADIRECTINPUTVERSION)
+ CHECK_RESULT(DIERR_BADDRIVERVER)
+ CHECK_RESULT(DIERR_DEVICENOTREG)
+ CHECK_RESULT(DIERR_NOTFOUND)
+ //CHECK_RESULT(DIERR_OBJECTNOTFOUND)
+ CHECK_RESULT(DIERR_INVALIDPARAM)
+ CHECK_RESULT(DIERR_NOINTERFACE)
+ CHECK_RESULT(DIERR_GENERIC)
+ CHECK_RESULT(DIERR_OUTOFMEMORY)
+ CHECK_RESULT(DIERR_UNSUPPORTED)
+ CHECK_RESULT(DIERR_NOTINITIALIZED)
+ CHECK_RESULT(DIERR_ALREADYINITIALIZED)
+ CHECK_RESULT(DIERR_NOAGGREGATION)
+ CHECK_RESULT(DIERR_OTHERAPPHASPRIO)
+ CHECK_RESULT(DIERR_INPUTLOST)
+ CHECK_RESULT(DIERR_ACQUIRED)
+ CHECK_RESULT(DIERR_NOTACQUIRED)
+ //CHECK_RESULT(DIERR_READONLY)
+ //CHECK_RESULT(DIERR_HANDLEEXISTS)
+ CHECK_RESULT(DIERR_INSUFFICIENTPRIVS)
+ CHECK_RESULT(DIERR_DEVICEFULL)
+ CHECK_RESULT(DIERR_MOREDATA)
+ CHECK_RESULT(DIERR_NOTDOWNLOADED)
+ CHECK_RESULT(DIERR_HASEFFECTS)
+ CHECK_RESULT(DIERR_NOTEXCLUSIVEACQUIRED)
+ CHECK_RESULT(DIERR_INCOMPLETEEFFECT)
+ CHECK_RESULT(DIERR_NOTBUFFERED)
+ CHECK_RESULT(DIERR_EFFECTPLAYING)
+ CHECK_RESULT(DIERR_UNPLUGGED)
+ CHECK_RESULT(DIERR_REPORTFULL)
+ default: sprintf(tszMessage, "Unknown"); break;
+ }
+ PrintOutput(tszMessage);
+}
+
+/*
+ ******************************************************************************
+ * DirectInputEnvironmentPlugin
+ ******************************************************************************
+ */
+
+/*
+ * Initialize all class, method, and field IDs
+ */
+BOOL InitIDs(JNIEnv* env) {
+ CLASS_AxisIdentifier =
+ env->FindClass("net/java/games/input/Axis$Identifier");
+ if (CLASS_AxisIdentifier == NULL) {
+ return FALSE;
+ }
+ FID_X = env->GetStaticFieldID(CLASS_AxisIdentifier, "X",
+ FD_AxisIdentifier);
+ if (FID_X == NULL) {
+ return FALSE;
+ }
+ FID_Y = env->GetStaticFieldID(CLASS_AxisIdentifier, "Y",
+ FD_AxisIdentifier);
+ if (FID_Y == NULL) {
+ return FALSE;
+ }
+ FID_Z = env->GetStaticFieldID(CLASS_AxisIdentifier, "Z",
+ FD_AxisIdentifier);
+ if (FID_Z == NULL) {
+ return FALSE;
+ }
+ FID_RX = env->GetStaticFieldID(CLASS_AxisIdentifier, "RX",
+ FD_AxisIdentifier);
+ if (FID_RX == NULL) {
+ return FALSE;
+ }
+ FID_RY = env->GetStaticFieldID(CLASS_AxisIdentifier, "RY",
+ FD_AxisIdentifier);
+ if (FID_RY == NULL) {
+ return FALSE;
+ }
+ FID_RZ = env->GetStaticFieldID(CLASS_AxisIdentifier, "RZ",
+ FD_AxisIdentifier);
+ if (FID_RZ == NULL) {
+ return FALSE;
+ }
+ FID_Slider = env->GetStaticFieldID(CLASS_AxisIdentifier, "SLIDER",
+ FD_AxisIdentifier);
+ if (FID_Slider == NULL) {
+ return FALSE;
+ }
+ FID_Button = env->GetStaticFieldID(CLASS_AxisIdentifier, "BUTTON",
+ FD_AxisIdentifier);
+ if (FID_Button == NULL) {
+ return FALSE;
+ }
+ FID_POV = env->GetStaticFieldID(CLASS_AxisIdentifier, "POV",
+ FD_AxisIdentifier);
+ if (FID_POV == NULL) {
+ return FALSE;
+ }
+ CLASS_ButtonIdentifier =
+ env->FindClass("net/java/games/input/Mouse$ButtonID");
+ if (CLASS_ButtonIdentifier == NULL) {
+ return FALSE;
+ }
+ FID_Left = env->GetStaticFieldID(CLASS_ButtonIdentifier, "LEFT",
+ FD_ButtonIdentifier);
+ if (FID_Left == NULL) {
+ return FALSE;
+ }
+ FID_Right = env->GetStaticFieldID(CLASS_ButtonIdentifier, "RIGHT",
+ FD_ButtonIdentifier);
+ if (FID_Right == NULL) {
+ return FALSE;
+ }
+ FID_Middle = env->GetStaticFieldID(CLASS_ButtonIdentifier, "MIDDLE",
+ FD_ButtonIdentifier);
+ if (FID_Middle == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputEnvironmentPlugin =
+ env->FindClass("net/java/games/input/DirectInputEnvironmentPlugin");
+ if (CLASS_DirectInputEnvironmentPlugin == NULL) {
+ return FALSE;
+ }
+ MID_AddDevice = env->GetMethodID(CLASS_DirectInputEnvironmentPlugin, "addDevice",
+ "(Ljava/util/ArrayList;JILjava/lang/String;Ljava/lang/String;Z)V");
+ if (MID_AddDevice == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputDevice =
+ env->FindClass("net/java/games/input/DirectInputDevice");
+ if (CLASS_DirectInputDevice == NULL) {
+ return FALSE;
+ }
+ MID_AddAxis = env->GetMethodID(CLASS_DirectInputDevice, "addAxis",
+ "(Ljava/util/ArrayList;Lnet/java/games/input/Axis$Identifier;ILjava/lang/String;)V");
+ if (MID_AddAxis == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputKeyboard =
+ env->FindClass("net/java/games/input/DirectInputKeyboard");
+ if (CLASS_DirectInputKeyboard == NULL) {
+ return FALSE;
+ }
+ MID_RenameKey = env->GetMethodID(CLASS_DirectInputKeyboard, "renameKey",
+ "(ILjava/lang/String;)V");
+ if (MID_RenameKey == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputMouse =
+ env->FindClass("net/java/games/input/DirectInputMouse");
+ if (CLASS_DirectInputMouse == NULL) {
+ return FALSE;
+ }
+ MID_RenameAxis = env->GetMethodID(CLASS_DirectInputMouse, "renameAxis",
+ "(Lnet/java/games/input/Axis$Identifier;Ljava/lang/String;)V");
+ if (MID_RenameAxis == NULL) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * WndProc for our dummy input window
+ */
+LRESULT CALLBACK DummyWndProc(
+ HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/*
+ * Register the dummy input window class
+ */
+BOOL RegisterDummyWindow(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)DummyWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = NULL;
+ wcex.hCursor = NULL;
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = (LPCSTR)NULL;
+ wcex.lpszClassName = DUMMY_WINDOW_NAME;
+ wcex.hIconSm = NULL;
+ return RegisterClassEx(&wcex);
+}
+
+/*
+ * Class: org_java_games_input_DirectInputEnvironmentPlugin
+ * Method: directInputCreate
+ * Signature: ()J
+ */
+extern "C" JNIEXPORT jlong JNICALL
+Java_net_java_games_input_DirectInputEnvironmentPlugin_directInputCreate
+ (JNIEnv* env, jobject obj)
+{
+ // Get our module handle
+ HINSTANCE hInst = GetModuleHandle(NULL);
+
+ // Register the dummy input window
+ if (!RegisterDummyWindow(hInst)) {
+ return (jlong)0;
+ }
+
+ // Create the dummy input window
+ hwndDummy = CreateWindow(DUMMY_WINDOW_NAME, NULL,
+ WS_POPUP | WS_ICONIC,
+ 0, 0, 0, 0, NULL, NULL, hInst, NULL);
+ if (hwndDummy == NULL)
+ {
+ return (jlong)0;
+ }
+
+ // Create the IDirectInput object
+ DWORD dwVersion = DIRECTINPUT_VERSION;
+ LPDIRECTINPUT8 lpDirectInput = NULL;
+ HRESULT res;
+ if (FAILED(res = DirectInput8Create(hInst, DIRECTINPUT_VERSION,
+ IID_IDirectInput8,(VOID **)&lpDirectInput, NULL))){
+ PrintDIError("DirectInputCreate", res);
+ return (jlong)0;
+ }
+
+ // Initialize method, class, and field IDs
+ if (!InitIDs(env)) {
+ lpDirectInput->Release();
+ return (jlong)0;
+ }
+
+ return (jlong)(long)lpDirectInput;
+}
+
+/*
+ * Enumeration callback for devices
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+
+/** mikes old enum callback
+BOOL CALLBACK EnumDeviceCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+ DeviceParamData* pData = (DeviceParamData*)pvRef;
+ LPDIRECTINPUT8 lpDirectInput = pData->lpDirectInput;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ LPDIRECTINPUTDEVICE8 lpDevice = NULL;
+ LPUNKNOWN pUnknown = NULL;
+
+ // Create the device object
+ HRESULT res = lpDirectInput->CreateDevice(lpddi->guidInstance, &lpDevice,
+ pUnknown);
+ if (res != DI_OK) {
+ PrintDIError("CreateDevice", res);
+ return DIENUM_STOP;
+ }
+
+ LPDIRECTINPUTDEVICE8 lpDevice2 = NULL;
+ // Get the IDirectDrawDevice8 interface from the object
+ res = lpDevice->QueryInterface(IID_IDirectInputDevice8,
+ (void**)&lpDevice2);
+ if (res != DI_OK) {
+ PrintDIError("QueryInterface DID2", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the data format
+ DWORD category = GET_DIDEVICE_TYPE(lpddi->dwDevType);
+ LPCDIDATAFORMAT lpDataFormat = &c_dfDIJoystick;
+ if (category == DI8DEVTYPE_MOUSE) {
+ lpDataFormat = &c_dfDIMouse;
+ } else if (category == DI8DEVTYPE_KEYBOARD) {
+ lpDataFormat = &c_dfDIKeyboard;
+ }
+ res = lpDevice2->SetDataFormat(lpDataFormat);
+ if (res != DI_OK) {
+ PrintDIError("SetDataFormat", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // If we are the mouse, we have to buffer the data
+ if (category == DI8DEVTYPE_MOUSE) {
+ DIPROPDWORD dipropdw;
+ dipropdw.diph.dwSize = sizeof(DIPROPDWORD);
+ dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dipropdw.diph.dwObj = 0;
+ dipropdw.diph.dwHow = DIPH_DEVICE;
+ dipropdw.dwData = BUFFER_SIZE;
+ res = lpDevice2->SetProperty(DIPROP_BUFFERSIZE, &dipropdw.diph);
+ if (res != DI_OK) {
+ PrintDIError("SetProperty", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ }
+
+ // Set the cooperative level
+ res = lpDevice2->SetCooperativeLevel(hwndDummy,
+ DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
+ if (res != DI_OK) {
+ PrintDIError("SetCooperativeLevel", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Acquire the device
+ res = lpDevice2->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the variables for the Java callback
+ jint type = (jint)lpddi->dwDevType;
+ jstring productName = env->NewStringUTF(lpddi->tszProductName);
+ if (productName == NULL) {
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jstring instanceName = env->NewStringUTF(lpddi->tszInstanceName);
+ if (instanceName == NULL) {
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Add the device into the list
+ env->CallVoidMethod(obj, MID_AddDevice, list, (jlong)(long)lpDevice2, type,
+ productName, instanceName);
+ return DIENUM_CONTINUE;
+}
+*/
+/** jeff's new enum callback */
+BOOL CALLBACK EnumDeviceCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+ DeviceParamData* pData = (DeviceParamData*)pvRef;
+ LPDIRECTINPUT8 lpDirectInput = pData->lpDirectInput;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ LPDIRECTINPUTDEVICE8 lpDevice = NULL;
+ LPUNKNOWN pUnknown = NULL;
+ HRESULT res;
+
+ // Create the device object
+ if (FAILED(res = lpDirectInput->CreateDevice(lpddi->guidInstance, &lpDevice,
+ pUnknown))){
+ PrintDIError("CreateDevice", res);
+ return DIENUM_STOP;
+ }
+
+ /*
+ LPDIRECTINPUTDEVICE8 lpDevice2 = NULL;
+ // Get the IDirectDrawDevice8 interface from the object
+ res = lpDevice->QueryInterface(IID_IDirectInputDevice8,
+ (void**)&lpDevice2);
+ if (res != DI_OK) {
+ PrintDIError("QueryInterface DID2", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ */
+
+ // Set the data format
+ LPCDIDATAFORMAT lpDataFormat;
+ DWORD category = GET_DIDEVICE_TYPE(lpddi->dwDevType)&0xFF;
+ switch (category){
+ case DI8DEVTYPE_KEYBOARD:
+ //printf("found Keyboard\n");
+ lpDataFormat = &c_dfDIKeyboard;
+ break;
+ case DI8DEVTYPE_MOUSE:
+ //printf("found mouse\n");
+ lpDataFormat = &c_dfDIMouse;
+ // set up buffering
+ DIPROPDWORD dipropdw;
+ dipropdw.diph.dwSize = sizeof(DIPROPDWORD);
+ dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dipropdw.diph.dwObj = 0;
+ dipropdw.diph.dwHow = DIPH_DEVICE;
+ dipropdw.dwData = BUFFER_SIZE;
+ if (FAILED(
+ res = lpDevice->SetProperty(DIPROP_BUFFERSIZE,
+ &dipropdw.diph))) {
+ PrintDIError("SetProperty", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ break;
+ case DI8DEVTYPE_JOYSTICK:
+ default:
+ //printf("found stick\n");
+ lpDataFormat = &c_dfDIJoystick;
+ break;
+ }
+
+ if (FAILED(res = lpDevice->SetDataFormat(lpDataFormat))){
+ PrintDIError("SetDataFormat", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the cooperative level
+ if(FAILED(res = lpDevice->SetCooperativeLevel(hwndDummy,
+ DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))){
+ PrintDIError("SetCooperativeLevel", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // get polling
+ DIDEVCAPS didc;
+ // Allocate space for all the device's objects (axes, buttons, POVS)
+ ZeroMemory( &didc, sizeof(DIDEVCAPS) );
+ didc.dwSize = sizeof(DIDEVCAPS);
+ if (FAILED(res=lpDevice->GetCapabilities(&didc))){
+ PrintDIError("Get Device Capabilities", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jboolean polled = JNI_FALSE;
+ if ((didc.dwFlags)&DIDC_POLLEDDATAFORMAT) {
+ polled = JNI_TRUE;
+ }
+
+ // Acquire the device
+ if(FAILED(res = lpDevice->Acquire())){
+ PrintDIError("Acquire", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the variables for the Java callback
+ jint type = (jint)lpddi->dwDevType&0xffff;
+ //printf("type == %x\n",type);
+ jstring productName = env->NewStringUTF(lpddi->tszProductName);
+ if (productName == NULL) {
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jstring instanceName = env->NewStringUTF(lpddi->tszInstanceName);
+ if (instanceName == NULL) {
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Add the device into the list
+ env->CallVoidMethod(obj, MID_AddDevice, list, (jlong)(long)lpDevice, type,
+ productName, instanceName,(jboolean)polled);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputEnvironmentPlugin
+ * Method: enumDevices
+ * Signature: (JLjava/util/ArrayList;)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputEnvironmentPlugin_enumDevices
+ (JNIEnv* env, jobject obj, jlong lDirectInput, jobject list)
+{
+ LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(long)lDirectInput;
+ DWORD dwDevType = DI8DEVCLASS_ALL;
+ DeviceParamData data(lpDirectInput, env, obj, list);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIEDFL_ATTACHEDONLY;
+ HRESULT res;
+ if(FAILED(res=lpDirectInput->EnumDevices(dwDevType,
+ EnumDeviceCallback, pvRef, dwFlags))){
+ PrintDIError("EnumDevices", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputDevice
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputDevice
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputDevice_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jintArray baData,
+ jboolean pollme)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Poll the device
+ if (pollme == JNI_TRUE) {
+ res = lpDevice->Poll();
+ if (res != DI_OK) {
+ PrintDIError("Poll", res);
+ return JNI_FALSE;
+ }
+ }
+ // Get the device state (data)
+ DIJOYSTATE data;
+ res = lpDevice->GetDeviceState(sizeof(data), &data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ // Copy the data into the byte array
+ env->SetIntArrayRegion(baData, 0, (jsize)(sizeof(data)/4), (jint*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback for device objects
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ jobject identifier = NULL;
+ HRESULT res;
+ if (lpddoi->guidType == GUID_XAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_X);
+ } else if (lpddoi->guidType == GUID_YAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Y);
+ } else if (lpddoi->guidType == GUID_ZAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Z);
+ } else if (lpddoi->guidType == GUID_RxAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RX);
+ } else if (lpddoi->guidType == GUID_RyAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RY);
+ } else if (lpddoi->guidType == GUID_RzAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RZ);
+ } else if (lpddoi->guidType == GUID_Slider) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Slider);
+ } else if (lpddoi->guidType == GUID_Button) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Button);
+ } else if (lpddoi->guidType == GUID_POV) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_POV);
+ } else {
+ // Do not add this axis into the list, since we don't know what it is
+ return DIENUM_CONTINUE;
+ }
+ if (identifier == NULL) {
+ return DIENUM_STOP;
+ }
+ if (DIDFT_GETTYPE(lpddoi->dwType)&DIDFT_AXIS){
+ // set axis range
+ DIPROPRANGE joy_axis_range;
+ joy_axis_range.lMin = -32768;
+ joy_axis_range.lMax = 32768;
+ joy_axis_range.diph.dwSize=sizeof(DIPROPRANGE);
+ joy_axis_range.diph.dwHeaderSize=sizeof(DIPROPHEADER);
+ joy_axis_range.diph.dwHow = DIPH_BYID;
+ joy_axis_range.diph.dwObj=lpddoi->dwType;
+ if (FAILED(
+ res=lpDevice->SetProperty(DIPROP_RANGE,&joy_axis_range.diph))){
+ PrintDIError("SetProperty", res);
+ }
+ }
+ jint didft = (jint)lpddoi->dwType;
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ // Add the axis into our list
+ env->CallVoidMethod(obj, MID_AddAxis, list, identifier, didft,
+ name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputDevice
+ * Method: enumObjects
+ * Signature: (JLjava/util/ArrayList;)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputDevice_enumObjects
+ (JNIEnv* env, jobject obj, jlong lDevice, jobject list)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, list);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(EnumObjectsCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputKeyboard
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputKeyboard
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputKeyboard_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Get the device state (data)
+ char data[256];
+ res = lpDevice->GetDeviceState(sizeof(data), data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback to rename keyboard keys
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK RenameKeysCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jint index = (jint)lpddoi->dwOfs;
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ env->CallVoidMethod(obj, MID_RenameKey, index, name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputKeyboard
+ * Method: renameKeys
+ * Signature: (J)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputKeyboard_renameKeys
+ (JNIEnv* env, jobject obj, jlong lDevice)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, NULL);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(RenameKeysCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputMouse
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputMouse
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputMouse_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Get the data
+ DIMOUSESTATE data;
+ res = lpDevice->GetDeviceState(sizeof(data), &data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ // Set the data in our array
+ env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback to rename mouse axes
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK RenameAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject identifier;
+ switch (lpddoi->dwOfs) {
+ case DIMOFS_X:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_X);
+ break;
+ case DIMOFS_Y:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_Y);
+ break;
+ case DIMOFS_Z:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_Slider);
+ break;
+ case DIMOFS_BUTTON0:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Left);
+ break;
+ case DIMOFS_BUTTON1:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Right);
+ break;
+ case DIMOFS_BUTTON2:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Middle);
+ break;
+ case DIMOFS_BUTTON3:
+ default:
+ return DIENUM_CONTINUE; // Not an axis we know
+ }
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ env->CallVoidMethod(obj, MID_RenameAxis, identifier, name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputMouse
+ * Method: renameAxes
+ * Signature: (J)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputMouse_renameAxes
+ (JNIEnv* env, jobject obj, jlong lDevice)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, NULL);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(RenameAxesCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+