void vrpn_Griffin_PowerMate::decodePacket(size_t bytes, vrpn_uint8 *buffer) {
	// Decode all full reports, each of which is 8 bytes long.
        // Because there is only one type of report, the initial "0" report-type
        // byte is removed by the HIDAPI driver.
	// XXX Check to see that this works with HIDAPI, there may be two smaller reports.
	if (bytes == 6) {

		if (vrpn_Dial::num_dials > 0) {
			// dial (2nd byte)
			// Do the unsigned/signed conversion at the last minute so the
			// signed values work properly.
			dials[0] = static_cast<vrpn_int8>(buffer[1]);
		} else {
			// dial (2nd byte)
			normalize_axis(buffer[1], 5, 1.0f, channel[0]);
		}

		vrpn_uint8 value;
		// switches (1st byte):
		value = buffer[0];
		//	button #0: 01 button
		for (int btn = 0; btn < 1; btn++) {
			vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << (btn % 8));
			buttons[btn] = ((value & mask) != 0);
		}
	} else {
		fprintf(stderr, "vrpn_Griffin_PowerMate: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
	}
}
Exemple #2
0
void vrpn_Contour_ShuttleXpress::decodePacket(size_t bytes, vrpn_uint8 *buffer) {
	// Decode all full reports, each of which is 5 bytes long.
        // Because there is only one type of report, the initial "0" report-type
        // byte is removed by the HIDAPI driver.
	if (bytes == 5) {
		if (!_gotDial) {
			_gotDial = true;
		}
		else {
			dials[0] = static_cast<vrpn_int8>(buffer[1] - _lastDial) / 10.0;
		}
		_lastDial = buffer[1];

		// analog (1st byte): 0 center, 1..7 right, -1..-7 left
		normalize_axis((unsigned int)((static_cast<float>(static_cast<vrpn_int8>(buffer[0])) * 128.0f / 7.0f) + 128.0f), 0, 1.0f, channel[0]);
		// Second analog integrates the dial value.
		channel[1] += dials[0];

		vrpn_uint8 value;
		// buttons (4th byte):
		value = buffer[3];
		for (int btn = 0; btn < 4; btn++) {
			vrpn_uint8 mask = static_cast<vrpn_uint8>((1 << (btn % 8)) << 4);
			buttons[btn] = ((value & mask) != 0);
		}
		// buttons (5th byte):
		value = buffer[4];
		for (int btn = 0; btn < 1; btn++) {
			vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << (btn % 8));
			buttons[btn + 4] = ((value & mask) != 0);
		}
	} else {
		fprintf(stderr, "vrpn_Contour_ShuttleXpress: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
	}
}
Exemple #3
0
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();
}
Exemple #4
0
void vrpn_Contour_ShuttleXpress::decodePacket(size_t bytes, vrpn_uint8 *buffer) {
	// Decode all full reports, each of which is 5 bytes long.
        // Because there is only one type of report, the initial "0" report-type
        // byte is removed by the HIDAPI driver.
	// XXX Check to see that this works with HIDAPI, there may be two smaller reports.
	if (bytes == 5) {
		static bool set = false;

		// analog (1st byte): 0 center, 1..7 right, -1..-7 left
		normalize_axis((unsigned int) ((static_cast<float>(static_cast<vrpn_int8>(buffer[0])) * 128.0f / 7.0f) + 128.0f), 0, 1.0f, channel[0]);

		if (vrpn_Dial::num_dials > 0)
		{
			// dial (2nd byte)
			// Do the unsigned/signed conversion at the last minute so the signed values work properly.
			dials[0] = static_cast<vrpn_int8>(buffer[1] - _lastDial);
			_lastDial = buffer[1];
		}
		else
		{
			// dial (2nd byte)
			normalize_axis((unsigned int) (static_cast<float>(static_cast<vrpn_int8>(buffer[1])) + 128.0f), 0, 1.0f, channel[1]);
		}

		vrpn_uint8 value;
		// buttons (4th byte):
		value = buffer[3];
		for (int btn = 0; btn < 4; btn++) {
			vrpn_uint8 mask = static_cast<vrpn_uint8>((1 << (btn % 8)) << 4);
			buttons[btn] = ((value & mask) != 0);
		}
		// buttons (5th byte):
		value = buffer[4];
		for (int btn = 0; btn < 1; btn++) {
			vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << (btn % 8));
			buttons[btn + 4] = ((value & mask) != 0);
		}
	} else {
		fprintf(stderr, "vrpn_Contour_ShuttleXpress: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
	}
}
static void normalize_axes(const unsigned int x, const unsigned int y, const short deadzone, const vrpn_float64 scale, vrpn_float64& channelX, vrpn_float64& channelY, int wordSize = 16)
{
#ifdef FUTURE
	// adapted from: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001%28v=vs.85%29.aspx
	// determine how far the controller is pushed
	float magnitude = (float) sqrt((double) ((x * x) + (y * y)));

	// determine the direction the controller is pushed
	float normalizedX = ((magnitude > 0.0f) ? (x / magnitude) : 0.0f);
	float normalizedY = ((magnitude > 0.0f) ? (y / magnitude) : 0.0f);

	float normalizedMagnitude = 0.0f;

	// check if the controller is outside a circular dead zone
	if (magnitude > deadzone)
	{
		// clip the magnitude at its expected maximum value
		if (magnitude > 32767)
		{
			magnitude = 32767;
		}

		// adjust magnitude relative to the end of the dead zone
		magnitude -= deadzone;

		// optionally normalize the magnitude with respect to its
		// expected range giving a magnitude value of 0.0 to 1.0
		normalizedMagnitude = magnitude / (32767.0f - deadzone);
	}
	else
	{	// if the controller is in the deadzone zero out the magnitude
		magnitude = 0.0f;
		normalizedMagnitude = 0.0f;
	}
#else
	normalize_axis(x, deadzone, scale, channelX, wordSize);
	normalize_axis(y, deadzone, scale, channelY, wordSize);
#endif // FUTURE
}
Exemple #6
0
void vrpn_Contour_ShuttlePROv2::decodePacket(size_t bytes, vrpn_uint8 *buffer)
{
	// Print the report so we can figure out what is going on.
/*	for (size_t i = 0; i < bytes; i++) {
	printf("%02x ", buffer[i]);
	}
	printf("\n");
	return; */

	// Decode all full reports, each of which is 5 bytes long.
	// Because there is only one type of report, the initial "0" report-type
	// byte is removed by the HIDAPI driver.
	if (bytes == 5) {
		if (!_gotDial) {
			_gotDial = true;
		}
		else {
			dials[0] = static_cast<vrpn_int8>(buffer[1] - _lastDial) / 10.0;
		}
		_lastDial = buffer[1];

		// analog (1st byte): 0 center, 1..7 right, -1..-7 left
		normalize_axis((unsigned int)((static_cast<float>(static_cast<vrpn_int8>(buffer[0])) * 128.0f / 7.0f) + 128.0f), 0, 1.0f, channel[0]);
		// Second analog integrates the dial value.
		channel[1] += dials[0];

		// Top row of four buttons, from left to right: index[bit]
		//   3[0], 3[1], 3[2], 3[3]
		// Second row of 5 buttons, from left to right:
		//   3[4], 3[5], 3[6], 3[7], 4[0]
		// Four lower buttons, from left to right and then down to next row:
		//   4[1], 4[2], 4[3], 4[4]
		// Two black buttons, from left to right:
		//   4[5], 4[6]
		for (int btn = 0; btn <= 15; btn++) {
			vrpn_uint8 *offset, mask;

			offset = buffer + btn / 8 + 3;
			mask = static_cast<vrpn_uint8>(1 << (btn % 8));

			buttons[btn] = (*offset & mask) != 0;
		}
	}
	else {
		fprintf(stderr, "vrpn_Contour_ShuttlePROv2: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
	}
}
static void normalize_axes(const unsigned int x, const unsigned int y, const short deadzone, const vrpn_float64 scale, vrpn_float64& channelX, vrpn_float64& channelY, int wordSize = 16)
{
	normalize_axis(x, deadzone, scale, channelX, wordSize);
	normalize_axis(y, deadzone, scale, channelY, wordSize);
}
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]);
	}
Exemple #9
0
void vrpn_Retrolink_GameCube::decodePacket(size_t bytes, vrpn_uint8 *buffer)
{
	/*
	// Print the report so we can figure out what is going on.
	for (size_t i = 0; i < bytes; i++) {
		printf("%02x ", buffer[i]);
	}
	printf("\n");
	return;
	*/

	// Because there is only one type of report, the initial "0" report-type
	// byte is removed by the HIDAPI driver.
	// Reports should be 8 bytes.  They are encoded as follows:
	// 0 = Left joystick X axis, goes from 0 (left) to 255 (right)
	// 1 = Left joystick Y axis, goes from 0 (up) to 255 (down)
	// 2 = Uncontrolled jibberish, must be from an unconnected channel
	// 3 = Left joystick X axis, goes from 0 (left) to 255 (right)
	// 4 = Left joystick Y axis, goes from 0 (left) to 255 (right)
	// 5 upper nybble = bit 0 (Y), 1 (X), 2 (A), 3 (B)
	// 5 lower nybble = rocker: 255 when nothing; 0 (up), 1 (UR), 2 (right), .. 7 (UL)
	// 6 = bit # 0 (left trigger), 1 (right trigger), 2 (Z), 5 (Start/pause)
	// 7 = always 0x20 (maybe unconnected buttons; probably safest to ignore)

	// Controls for the Nintendo 64 classic
	// 0 = Left joystick X axis, goes from 0 (left) to 255 (right)
	// 1 = Left joystick Y axis, goes from 0 (up) to 255 (down)
	// 2 = Uncontrolled jibberish, must be from an unconnected channel
	// 5 upper nybble = bit 0 (C up), 1 (C right), 2 (C down), 3 (C Left)
	// 5 lower nybble = rocker: 255 when nothing; 0 (up), 1 (UR), 2 (right), .. 7 (UL)
	// 6 = bit # 0 (left trigger), 1 (right trigger), 2 (A), 3 (Z), 4 (B), 5 (Start)
	// 7 = always 0x20 (maybe unconnected buttons; probably safest to ignore)

	if (bytes == 8) {
		// Figure out the joystick axes.
		channel[0] = normalize_axis(buffer[0]);
		channel[1] = normalize_axis(buffer[1]);
		channel[2] = normalize_axis(buffer[3]);
		channel[3] = normalize_axis(buffer[4]);

		// Figure out the buttons.
		buttons[0] = (buffer[5] & (1 << 4)) != 0;
		buttons[1] = (buffer[5] & (1 << 5)) != 0;
		buttons[2] = (buffer[5] & (1 << 6)) != 0;
		buttons[3] = (buffer[5] & (1 << 7)) != 0;
		buttons[4] = (buffer[6] & (1 << 0)) != 0;
		buttons[5] = (buffer[6] & (1 << 1)) != 0;
		buttons[6] = (buffer[6] & (1 << 2)) != 0;
		buttons[7] = (buffer[6] & (1 << 5)) != 0;

		// Figure out the rocker.
		vrpn_uint8 rocker = buffer[5] & 0x0f;
		vrpn_float64 angle;
		bool up, right, down, left;
		angle_and_buttons_from_rocker_byte(rocker, &angle, &up, &right, &down, &left);
		channel[4] = angle;
		buttons[8] = up; buttons[9] = right;
		buttons[10] = down;
		buttons[11] = left;
	} else {
		fprintf(stderr, "vrpn_Retrolink_GameCube: Found a corrupted report; # total bytes = %u\n", static_cast<unsigned>(bytes));
	}
}
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]);
	}