static void dinput_poll(void *data) { struct dinput_input *di = (struct dinput_input*)data; memset(di->state, 0, sizeof(di->state)); if (di->keyboard) { if (FAILED(IDirectInputDevice8_GetDeviceState( di->keyboard, sizeof(di->state), di->state))) { IDirectInputDevice8_Acquire(di->keyboard); if (FAILED(IDirectInputDevice8_GetDeviceState( di->keyboard, sizeof(di->state), di->state))) memset(di->state, 0, sizeof(di->state)); } } if (di->mouse) { DIMOUSESTATE2 mouse_state; memset(&mouse_state, 0, sizeof(mouse_state)); if (FAILED(IDirectInputDevice8_GetDeviceState( di->mouse, sizeof(mouse_state), &mouse_state))) { IDirectInputDevice8_Acquire(di->mouse); if (FAILED(IDirectInputDevice8_GetDeviceState( di->mouse, sizeof(mouse_state), &mouse_state))) memset(&mouse_state, 0, sizeof(mouse_state)); } di->mouse_last_x = di->mouse_x; di->mouse_last_y = di->mouse_y; di->mouse_x = di->window_pos_x; di->mouse_y = di->window_pos_y; if (!mouse_state.rgbButtons[0]) unset_doubleclick_on_titlebar(); if (doubleclick_on_titlebar_pressed()) di->mouse_l = 0; else di->mouse_l = mouse_state.rgbButtons[0]; di->mouse_r = mouse_state.rgbButtons[1]; di->mouse_m = mouse_state.rgbButtons[2]; /* No simple way to get absolute coordinates * for RETRO_DEVICE_POINTER. Just use Win32 APIs. */ POINT point = {0}; GetCursorPos(&point); ScreenToClient((HWND)video_driver_window_get(), &point); di->mouse_x = point.x; di->mouse_y = point.y; } if (di->joypad) di->joypad->poll(); }
static void dinput_poll(void *data) { struct dinput_input *di = (struct dinput_input*)data; memset(di->state, 0, sizeof(di->state)); if (di->keyboard) { if (FAILED(IDirectInputDevice8_GetDeviceState( di->keyboard, sizeof(di->state), di->state))) { IDirectInputDevice8_Acquire(di->keyboard); if (FAILED(IDirectInputDevice8_GetDeviceState( di->keyboard, sizeof(di->state), di->state))) memset(di->state, 0, sizeof(di->state)); } } if (di->mouse) { DIMOUSESTATE2 mouse_state; memset(&mouse_state, 0, sizeof(mouse_state)); if (FAILED(IDirectInputDevice8_GetDeviceState( di->mouse, sizeof(mouse_state), &mouse_state))) { IDirectInputDevice8_Acquire(di->mouse); if (FAILED(IDirectInputDevice8_GetDeviceState( di->mouse, sizeof(mouse_state), &mouse_state))) memset(&mouse_state, 0, sizeof(mouse_state)); } di->mouse_rel_x = mouse_state.lX; di->mouse_rel_y = mouse_state.lY; di->mouse_l = mouse_state.rgbButtons[0]; di->mouse_r = mouse_state.rgbButtons[1]; di->mouse_m = mouse_state.rgbButtons[2]; di->mouse_wu = mouse_state.rgbButtons[3]; di->mouse_wd = mouse_state.rgbButtons[4]; /* No simple way to get absolute coordinates * for RETRO_DEVICE_POINTER. Just use Win32 APIs. */ POINT point = {0}; GetCursorPos(&point); ScreenToClient((HWND)driver.video_window, &point); di->mouse_x = point.x; di->mouse_y = point.y; } if (di->joypad) di->joypad->poll(); }
static void dinput_joypad_poll(void) { unsigned i; for (i = 0; i < MAX_USERS; i++) { struct dinput_joypad *pad = &g_pads[i]; bool polled = g_xinput_pad_indexes[i] < 0; if (!pad || !pad->joypad || !polled) continue; memset(&pad->joy_state, 0, sizeof(pad->joy_state)); if (FAILED(IDirectInputDevice8_Poll(pad->joypad))) { if (FAILED(IDirectInputDevice8_Acquire(pad->joypad))) { memset(&pad->joy_state, 0, sizeof(DIJOYSTATE2)); continue; } /* If this fails, something *really* bad must have happened. */ if (FAILED(IDirectInputDevice8_Poll(pad->joypad))) { memset(&pad->joy_state, 0, sizeof(DIJOYSTATE2)); continue; } } IDirectInputDevice8_GetDeviceState(pad->joypad, sizeof(DIJOYSTATE2), &pad->joy_state); } }
static void dinput_joypad_poll(void) { for (unsigned i = 0; i < MAX_PLAYERS; i++) { struct dinput_joypad *pad = &g_pads[i]; if ((pad->joypad) && (g_xbox_pad_indexes[i] == -1)) { memset(&pad->joy_state, 0, sizeof(pad->joy_state)); if (FAILED(IDirectInputDevice8_Poll(pad->joypad))) { if (FAILED(IDirectInputDevice8_Acquire(pad->joypad))) { memset(&pad->joy_state, 0, sizeof(DIJOYSTATE2)); continue; } // If this fails, something *really* bad must have happened. if (FAILED(IDirectInputDevice8_Poll(pad->joypad))) { memset(&pad->joy_state, 0, sizeof(DIJOYSTATE2)); continue; } } IDirectInputDevice8_GetDeviceState(pad->joypad, sizeof(DIJOYSTATE2), &pad->joy_state); } } }
static HRESULT Poll(IDirectInputDevice8A * joystick, DIJOYSTATE * state) { HRESULT hr; hr = IDirectInputDevice8_Poll(joystick); /* Try to acquire the joystick */ if (FAILED(hr)) { hr = IDirectInputDevice8_Acquire(joystick); while (hr == DIERR_INPUTLOST) hr = IDirectInputDevice8_Acquire(joystick); if (hr == DIERR_INVALIDPARAM || hr == DIERR_NOTINITIALIZED) return E_FAIL; if (hr == DIERR_OTHERAPPHASPRIO) return S_OK; } hr = IDirectInputDevice8_GetDeviceState(joystick, sizeof(DIJOYSTATE), state); /* Should not fail, the device has just been acquired */ if (FAILED(hr)) return hr; return S_OK; }
JNIEXPORT jint JNICALL Java_net_java_games_input_IDirectInputDevice_nGetDeviceState(JNIEnv *env, jclass unused, jlong address, jintArray device_state_array) { LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(INT_PTR)address; jsize state_length = (*env)->GetArrayLength(env, device_state_array); DWORD state_size = state_length*sizeof(jint); HRESULT res; jint *device_state = (*env)->GetIntArrayElements(env, device_state_array, NULL); if (device_state == NULL) return -1; res = IDirectInputDevice8_GetDeviceState(lpDevice, state_size, device_state); (*env)->ReleaseIntArrayElements(env, device_state_array, device_state, 0); return res; }
static void poll_input(const struct Joystick *joy, DIJOYSTATE *state) { HRESULT hr; hr = IDirectInputDevice8_Poll(joy->device); /* If it failed, try to acquire the joystick */ if (FAILED(hr)) { hr = IDirectInputDevice8_Acquire(joy->device); while (hr == DIERR_INPUTLOST) hr = IDirectInputDevice8_Acquire(joy->device); } if (hr == DIERR_OTHERAPPHASPRIO) return; IDirectInputDevice8_GetDeviceState(joy->device, sizeof(DIJOYSTATE), state); }
/* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ static void UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) { DIJOYSTATE2 state; HRESULT result; int i; result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, sizeof(DIJOYSTATE2), &state); } if (result != DI_OK) { joystick->hwdata->send_remove_event = SDL_TRUE; joystick->hwdata->removed = SDL_TRUE; return; } /* Set each known axis, button and POV. */ for (i = 0; i < joystick->hwdata->NumInputs; ++i) { const input_t *in = &joystick->hwdata->Inputs[i]; switch (in->type) { case AXIS: switch (in->ofs) { case DIJOFS_X: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lX); break; case DIJOFS_Y: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lY); break; case DIJOFS_Z: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lZ); break; case DIJOFS_RX: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRx); break; case DIJOFS_RY: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRy); break; case DIJOFS_RZ: SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRz); break; case DIJOFS_SLIDER(0): SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[0]); break; case DIJOFS_SLIDER(1): SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[1]); break; } break; case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]); SDL_PrivateJoystickHat(joystick, in->num, pos); break; } } } }
static gboolean dx_dinput_setup_events (ControllerDXDInput *controller, GError **error) { HRESULT hresult; DIPROPDWORD dword; gint i, k; DXDInputSource *source; if ((controller->event = CreateEvent (NULL, TRUE, FALSE, NULL)) == NULL) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "CreateEvent failed: %s", g_win32_error_message (GetLastError ())); return FALSE; } controller->format = g_new (DIDATAFORMAT, 1); controller->format->dwSize = sizeof (DIDATAFORMAT); controller->format->dwObjSize = sizeof (DIOBJECTDATAFORMAT); dword.diph.dwSize = sizeof (DIPROPDWORD); dword.diph.dwHeaderSize = sizeof (DIPROPHEADER); dword.diph.dwObj = 0; dword.diph.dwHow = DIPH_DEVICE; /* Get the axis mode so we can use the same in the format */ if (FAILED ((hresult = IDirectInputDevice8_GetProperty (controller->didevice8, DIPROP_AXISMODE, &dword.diph)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::GetParameters failed: %s", g_win32_error_message (hresult)); goto fail0; } controller->format->dwFlags = dword.dwData + 1; controller->format->dwNumObjs = controller->num_buttons + controller->num_axes + controller->num_sliders + controller->num_povs; controller->format->rgodf = g_new (DIOBJECTDATAFORMAT, controller->format->dwNumObjs); k = 0; controller->format->dwDataSize = 0; for (i = 0; i < controller->num_buttons; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_BUTTON | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = 0; controller->format->dwDataSize += 1; k++; } controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4); for (i = 0; i < controller->num_axes; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION; controller->format->dwDataSize += 4; k++; } for (i = 0; i < controller->num_sliders; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_AXIS | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = DIDOI_ASPECTPOSITION; controller->format->dwDataSize += 4; k++; } for (i = 0; i < controller->num_povs; i++) { controller->format->rgodf[k].pguid = NULL; controller->format->rgodf[k].dwOfs = controller->format->dwDataSize; controller->format->rgodf[k].dwType = DIDFT_POV | DIDFT_MAKEINSTANCE (i); controller->format->rgodf[k].dwFlags = 0; controller->format->dwDataSize += 4; k++; } g_assert (k == controller->format->dwNumObjs); controller->format->dwDataSize = 4*((controller->format->dwDataSize + 3)/4); controller->prevdata = g_malloc (controller->format->dwDataSize); dump_data_format (controller->format); if (FAILED ((hresult = IDirectInputDevice8_SetDataFormat (controller->didevice8, controller->format)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::SetDataFormat failed: %s", g_win32_error_message (hresult)); goto fail1; } if (FAILED ((hresult = IDirectInputDevice8_SetEventNotification (controller->didevice8, controller->event)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::SetEventNotification failed: %s", g_win32_error_message (hresult)); goto fail2; } if (FAILED ((hresult = IDirectInputDevice8_Acquire (controller->didevice8)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::Acquire failed: %s", g_win32_error_message (hresult)); goto fail2; } if (FAILED ((hresult = IDirectInputDevice8_GetDeviceState (controller->didevice8, controller->format->dwDataSize, controller->prevdata)))) { g_set_error (error, GIMP_MODULE_ERROR, GIMP_MODULE_FAILED, "IDirectInputDevice8::GetDeviceState failed: %s", g_win32_error_message (hresult)); goto fail2; } source = (DXDInputSource *) g_source_new (&dx_dinput_event_funcs, sizeof (DXDInputSource)); source->controller = controller; controller->source = (GSource *) source; controller->pollfd = g_new (GPollFD, 1); controller->pollfd->fd = (int) controller->event; controller->pollfd->events = G_IO_IN; g_source_add_poll (&source->source, controller->pollfd); g_source_attach (&source->source, NULL); return TRUE; fail2: IDirectInputDevice8_SetEventNotification (controller->didevice8, NULL); fail1: g_free (controller->format->rgodf); g_free (controller->format); controller->format = NULL; g_free (controller->prevdata); controller->prevdata = NULL; fail0: CloseHandle (controller->event); controller->event = 0; return FALSE; }
static gboolean dx_dinput_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { ControllerDXDInput * const input = ((DXDInputSource *) source)->controller; GimpController *controller = &input->parent_instance; const DIDATAFORMAT * const format = input->format; const DIOBJECTDATAFORMAT *rgodf = format->rgodf; guchar *data; gint i; GimpControllerEvent cevent = { 0, }; data = g_alloca (format->dwDataSize); if (FAILED (IDirectInputDevice8_GetDeviceState (input->didevice8, format->dwDataSize, data))) { return TRUE; } g_object_ref (controller); for (i = 0; i < input->num_buttons; i++) { if (input->prevdata[rgodf->dwOfs] != data[rgodf->dwOfs]) { if (data[rgodf->dwOfs] & 0x80) { /* Click event, compatibility with Linux Input */ cevent.any.type = GIMP_CONTROLLER_EVENT_TRIGGER; cevent.any.source = controller; cevent.any.event_id = i*NUM_EVENTS_PER_BUTTON; gimp_controller_event (controller, &cevent); /* Press event */ cevent.any.event_id = i*NUM_EVENTS_PER_BUTTON + 1; gimp_controller_event (controller, &cevent); } else { /* Release event */ cevent.any.type = GIMP_CONTROLLER_EVENT_TRIGGER; cevent.any.source = controller; cevent.any.event_id = i*NUM_EVENTS_PER_BUTTON + 2; gimp_controller_event (controller, &cevent); } } rgodf++; } for (i = 0; i < input->num_axes; i++) { LONG *prev = (LONG *)(input->prevdata+rgodf->dwOfs); LONG *curr = (LONG *)(data+rgodf->dwOfs); if (ABS (*prev - *curr) > 1) { cevent.any.type = GIMP_CONTROLLER_EVENT_VALUE; cevent.any.source = controller; cevent.any.event_id = input->num_button_events + i*NUM_EVENTS_PER_AXIS; g_value_init (&cevent.value.value, G_TYPE_DOUBLE); if (*curr - *prev < 0) { g_value_set_double (&cevent.value.value, *prev - *curr); } else { cevent.any.event_id++; g_value_set_double (&cevent.value.value, *curr - *prev); } gimp_controller_event (controller, &cevent); g_value_unset (&cevent.value.value); } else *curr = *prev; rgodf++; } for (i = 0; i < input->num_sliders; i++) { LONG *prev = (LONG *)(input->prevdata+rgodf->dwOfs); LONG *curr = (LONG *)(data+rgodf->dwOfs); if (ABS (*prev - *curr) > 1) { cevent.any.type = GIMP_CONTROLLER_EVENT_VALUE; cevent.any.source = controller; cevent.any.event_id = input->num_button_events + input->num_axis_events + i*NUM_EVENTS_PER_SLIDER; g_value_init (&cevent.value.value, G_TYPE_DOUBLE); if (*curr - *prev < 0) { g_value_set_double (&cevent.value.value, *prev - *curr); } else { cevent.any.event_id++; g_value_set_double (&cevent.value.value, *curr - *prev); } gimp_controller_event (controller, &cevent); g_value_unset (&cevent.value.value); } else *curr = *prev; rgodf++; } for (i = 0; i < input->num_povs; i++) { LONG prev = *((LONG *)(input->prevdata+rgodf->dwOfs)); LONG curr = *((LONG *)(data+rgodf->dwOfs)); double prevx, prevy; double currx, curry; if (prev != curr) { if (prev == -1) { prevx = 0.; prevy = 0.; } else { prevx = sin (prev/36000.*2.*G_PI); prevy = cos (prev/36000.*2.*G_PI); } if (curr == -1) { currx = 0.; curry = 0.; } else { currx = sin (curr/36000.*2.*G_PI); curry = cos (curr/36000.*2.*G_PI); } cevent.any.type = GIMP_CONTROLLER_EVENT_VALUE; cevent.any.source = controller; cevent.any.event_id = input->num_button_events + input->num_axis_events + input->num_slider_events + i*NUM_EVENTS_PER_POV; g_value_init (&cevent.value.value, G_TYPE_DOUBLE); g_value_set_double (&cevent.value.value, currx - prevx); gimp_controller_event (controller, &cevent); cevent.any.event_id++; g_value_set_double (&cevent.value.value, curry - prevy); gimp_controller_event (controller, &cevent); g_value_unset (&cevent.value.value); if (curr == -1) { cevent.any.type = GIMP_CONTROLLER_EVENT_TRIGGER; cevent.any.event_id++; gimp_controller_event (controller, &cevent); } } rgodf++; } g_assert (rgodf == format->rgodf + format->dwNumObjs); memmove (input->prevdata, data, format->dwDataSize); g_object_unref (controller); return TRUE; }
void I_GetJoystickState(joystate_t *state) { static BOOL oldButtons[IJOY_MAXBUTTONS]; // Thats a lot of buttons. DWORD tries, i; DIJOYSTATE dijoy; BOOL acquired; HRESULT hr; memset(state, 0, sizeof(*state)); // Initialization has not been done. if(!didJoy || !usejoystick || !initIOk) return; // Some joysticks need to be polled. IDirectInputDevice8_Poll(didJoy); tries = 1; acquired = FALSE; while(!acquired && tries > 0) { hr = IDirectInputDevice8_GetDeviceState(didJoy, sizeof(dijoy), &dijoy); if(SUCCEEDED(hr)) { acquired = TRUE; } else if(tries > 0) { // Try to reacquire. IDirectInputDevice8_Acquire(didJoy); tries--; } } if(!acquired) return; // The operation is a failure. state->numAxes = 8; state->axis[0] = (int) dijoy.lX; state->axis[1] = (int) dijoy.lY; state->axis[2] = (int) dijoy.lZ; state->axis[3] = (int) dijoy.lRx; state->axis[4] = (int) dijoy.lRy; state->axis[5] = (int) dijoy.lRz; state->axis[6] = (int) dijoy.rglSlider[0]; state->axis[7] = (int) dijoy.rglSlider[1]; state->numButtons = 32; for(i = 0; i < IJOY_MAXBUTTONS; ++i) { BOOL isDown = (dijoy.rgbButtons[i] & 0x80? TRUE : FALSE); state->buttonDowns[i] = state->buttonUps[i] = 0; if(isDown && !oldButtons[i]) state->buttonDowns[i] = 1; else if(!isDown && oldButtons[i]) state->buttonUps[i] = 1; oldButtons[i] = isDown; } state->numHats = 4; for(i = 0; i < IJOY_MAXHATS; ++i) { DWORD pov = dijoy.rgdwPOV[i]; if((pov & 0xffff) == 0xffff) state->hatAngle[i] = IJOY_POV_CENTER; else state->hatAngle[i] = pov / 100.0f; } }