void vrpn_XInputGamepad::mainloop() { XINPUT_STATE state; DWORD rv; server_mainloop(); if ((rv = XInputGetState(_controllerIndex, &state)) != ERROR_SUCCESS) { char errMsg[256]; struct timeval now; if (rv == ERROR_DEVICE_NOT_CONNECTED) sprintf(errMsg, "XInput device %u not connected", _controllerIndex); else sprintf(errMsg, "XInput device %u returned Windows error code %u", _controllerIndex, rv); vrpn_gettimeofday(&now, NULL); send_text_message(errMsg, now, vrpn_TEXT_ERROR); return; } // Set device state in VRPN_Analog channel[0] = normalize_axis(state.Gamepad.sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); channel[1] = normalize_axis(state.Gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); channel[2] = normalize_axis(state.Gamepad.sThumbRX, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); channel[3] = normalize_axis(state.Gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); channel[4] = normalize_dpad(state.Gamepad.wButtons); channel[5] = normalize_trigger(state.Gamepad.bLeftTrigger); channel[6] = normalize_trigger(state.Gamepad.bRightTrigger); // Set device state in VRPN_Button // Buttons are listed in DirectInput ordering buttons[0] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0; buttons[1] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0; buttons[2] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0; buttons[3] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0; buttons[4] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0; buttons[5] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0; buttons[6] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) != 0; buttons[7] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_START) != 0; buttons[8] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0; buttons[9] = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0; vrpn_gettimeofday(&_timestamp, NULL); report_changes(); }
void vrpn_Logitech_Extreme_3D_Pro::decodePacket(size_t bytes, vrpn_uint8 *buffer) { // SideWinder Precision 2 joystick // Decode all full reports, each of which is 40 bytes long. // Because there is only one type of report, the initial "0" report-type // byte is removed by the HIDAPI driver. /* ? [0]: X-axis (left=00, right=ff) [1]: Y-axis - lower byte (up=00, down=ff) [2]: POV Hat high nibble (none=0x80, N=0x00, NE=0x10, ... NW=0x80), Y-axis upper nibble in low nibble of this byte [3]: Z-rotate (left=00, right=ff) [4]: buttons (bit flags: none=0x00, "1" (trigger)=0x01, "2"=0x02, "3"=0x04, ..., "8"=0x80 [5]: Slider (up=00, down=ff) [6]: buttons (bit flags: none=0x00, "9"=0x01, "10"=0x02, "11"=0x04, "12"=0x08 */ // XXX Check to see that this works with HIDAPI, there may be two smaller reports. if (bytes == 7) { unsigned int x, y; x = buffer[0]; y = ((buffer[2] & 0x0f) << 8) + buffer[1]; normalize_axes(x, y, 0x16, 1.0f, channel[0], channel[1], 12); normalize_axis(buffer[3], 0x12, 1.0f, channel[2], 8); normalize_axis(buffer[5], 0x0e, 1.0f, channel[3], 8); vrpn_uint8 value, mask; value = buffer[4]; for (int btn = 0; btn < 8; btn++) { mask = static_cast<vrpn_uint8>(1 << (btn % 8)); buttons[btn] = ((value & mask) != 0); } // Point of View Hat buttons[8] = buttons[9] = buttons[10] = buttons[11] = 0; switch (buffer[2] >> 4) { case 0: // up buttons[8] = true; break; case 1: buttons[8] = buttons[9] = true; break; case 2: // right buttons[9] = true; break; case 3: buttons[9] = buttons[10] = true; break; case 4: // down buttons[10] = true; break; case 5: buttons[10] = buttons[11] = true; break; case 6: // left buttons[11] = true; break; case 7: buttons[11] = buttons[8] = true; break; case 8: default: // nothing to do break; } channel[4] = normalize_dpad(buttons[8], buttons[9], buttons[10], buttons[11]); }
void vrpn_Microsoft_SideWinder_Precision_2::decodePacket(size_t bytes, vrpn_uint8 *buffer) { // SideWinder Precision 2 joystick // Decode all full reports, each of which is 40 bytes long. // Because there is only one type of report, the initial "0" report-type // byte is removed by the HIDAPI driver. /* Byte : Bit 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 [0]: X-axis (left=00, right=ff) [1]: Y-axis (up=00, down=ff) [2]: Z-rotate (left=00, right=ff) [3]: Slider (up=00, down=ff) [4]: buttons (bit flags: none=0x00, "1" (trigger)=0x01, "2"=0x02, "3"=0x04, ..., "8"=0x80 [5]: POV Hat high nibble (none=0x80, N=0x00, NE=0x10, ... NW=0x80) */ // XXX Check to see that this works with HIDAPI, there may be two smaller reports. if (bytes == 6) { normalize_axes(buffer[0], buffer[1], 0x08, 1.0f, channel[0], channel[1], 8); normalize_axis(buffer[2], 0x08, 1.0f, channel[2], 8); normalize_axis(buffer[3], 0x08, 1.0f, channel[3], 8); vrpn_uint8 value, mask; value = buffer[4]; for (int btn = 0; btn < 8; btn++) { mask = static_cast<vrpn_uint8>(1 << (btn % 8)); buttons[btn] = ((value & mask) != 0); } // Point of View Hat buttons[8] = buttons[9] = buttons[10] = buttons[11] = 0; switch (buffer[5] >> 4) { case 0: // up buttons[8] = true; break; case 1: buttons[8] = buttons[9] = true; break; case 2: // right buttons[9] = true; break; case 3: buttons[9] = buttons[10] = true; break; case 4: // down buttons[10] = true; break; case 5: buttons[10] = buttons[11] = true; break; case 6: // left buttons[11] = true; break; case 7: buttons[11] = buttons[8] = true; break; case 8: default: // nothing to do break; } channel[4] = normalize_dpad(buttons[8], buttons[9], buttons[10], buttons[11]); }