vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_nVidia_shield_controller.C
Go to the documentation of this file.
1// vrpn_nVidia_shield_controller.C: VRPN driver for nVidia shield devices
2
3#include <stdio.h> // for fprintf, stderr, NULL
4#include <string.h> // for memset
5#include <math.h> // for fabs
6
9
10#if defined(VRPN_USE_HID)
11
12static const double POLL_INTERVAL = 1e+6 / 30.0; // If we have not heard, report.
13
14// USB vendor and product IDs for the models we support
15static const vrpn_uint16 NVIDIA_VENDOR = 0x955;
16static const vrpn_uint16 NVIDIA_SHIELD_USB = 0x7210;
17static const vrpn_uint16 NVIDIA_SHIELD_STEALTH_USB = 0x7214;
18
20 const char *name, vrpn_Connection *c,
21 vrpn_uint16 vendor, vrpn_uint16 product)
22 : vrpn_BaseClass(name, c)
23 , vrpn_HidInterface(filter, vendor, product)
24 , d_filter(filter)
25{
26 init_hid();
27}
28
30{
31 try {
32 delete d_filter;
33 } catch (...) {
34 fprintf(stderr, "vrpn_nVidia_shield::~vrpn_nVidia_shield(): delete failed\n");
35 return;
36 }
37}
38
41
42void vrpn_nVidia_shield::on_data_received(size_t bytes, vrpn_uint8 *buffer)
43{
44 decodePacket(bytes, buffer);
45}
46
48 : vrpn_nVidia_shield(new vrpn_HidProductAcceptor(NVIDIA_VENDOR, NVIDIA_SHIELD_USB), name, c, NVIDIA_VENDOR, NVIDIA_SHIELD_USB)
49 , vrpn_Analog(name, c)
50 , vrpn_Button_Filter(name, c)
51{
54
55 // Initialize the state of all the analogs and buttons
56 memset(buttons, 0, sizeof(buttons));
57 memset(lastbuttons, 0, sizeof(lastbuttons));
58 memset(channel, 0, sizeof(channel));
59 memset(last, 0, sizeof(last));
60}
61
63{
64 update();
66 struct timeval current_time;
67 vrpn_gettimeofday(&current_time, NULL);
68 if (vrpn_TimevalDuration(current_time, d_timestamp) > POLL_INTERVAL ) {
69 d_timestamp = current_time;
71
72 // Call the server_mainloop on our unique base class.
74 }
75}
76
77void vrpn_nVidia_shield_USB::report(vrpn_uint32 class_of_service) {
79 {
81 }
83 {
85 }
86
88 {
89 vrpn_Analog::report(class_of_service);
90 }
92 {
94 }
95}
96
97void vrpn_nVidia_shield_USB::report_changes(vrpn_uint32 class_of_service) {
99 {
101 }
103 {
105 }
106
108 {
109 vrpn_Analog::report_changes(class_of_service);
110 }
112 {
114 }
115}
116
117void vrpn_nVidia_shield_USB::decodePacket(size_t bytes, vrpn_uint8 *buffer)
118{
119 // There are two types of reports, type 1 is 15 bytes long (plus the
120 // type byte) and type 2 is 5 bytes long (plus the type byte)
121 // (On Linux, this shows up as a 16-byte message, even when it is
122 // type 2, on the mac it shows up as 6.)
123
124 if ( (bytes >= 6) && (buffer[0] == 2) ) {
125
126 // 6-byte reports. Thumb touch pad.
127 // Byte 0 is 02 (report type 2)
128 // Byte 1:
129 // Bit 0: pad button pressed
130 // Bit 7: finger touching pad
131 // Byte 2 seems to be X position, near 39 to left and near DF to right
132 // Byte 3 is 00
133 // Byte 4 seems to be Y position, near 33 at top and near 5B at bottom
134 // Byte 5 is 00
135
136 buttons[8] = ( (buffer[1] & (1 << 0)) != 0);
137 buttons[20] = ( (buffer[1] & (1 << 7)) != 0);
138 channel[6] = buffer[2] / 255.0;
139 channel[7] = buffer[4] / 255.0;
140
141 } else if ( (bytes == 16) && (buffer[0] == 1) ) {
142
143 // 16-byte reports.
144 // Byte 0 is 01 (report type 1)
145
146 // Byte 1:
147 // Bit 0: A button
148 // Bit 1: B button
149 // Bit 2: X button
150 // Bit 3: Y button
151 // Bit 4: Left finger trigger button
152 // Bit 5: Right finger trigger button
153 // Bit 6: Left joystick button
154 // Bit 7: Right joystick button
155 // Byte 2:
156 // Bit 0: Touch pad button pressed or center of volume control pressed
157 // or left of volume control pressed or right of volume control pressed
158 // Bit 1: Play/pause button pressed
159 // Bit 3: Right of volume control (+) pressed
160 // Bit 4: Left of volume control (-) pressed
161 // Bit 5: Shield emblem pressed
162 // Bit 6: Go Back button pressed
163 // Bit 7: Home button pressed
164
165 int first_byte = 1;
166 int num_bytes = 2;
167 int first_button = 0;
168 for (int byte = first_byte; byte < first_byte + num_bytes; byte++) {
169 vrpn_uint8 value = buffer[byte];
170 for (int btn = 0; btn < 8; btn++) {
171 vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << btn);
172 buttons[8*(byte - first_byte) + btn + first_button] = ((value & mask) != 0);
173 }
174
175 }
176
177 // Byte 3: Left hi-hat:
178 // 0F: Nothing pressed
179 // 0 = North, 1 = NE, 2 = E, 3 = SE, 4 = S, 5 = SW, 6 = W, 7 = NW
180 // This is encoded as buttons 16 (up), 17 (right), 18 (down), and 19 (left)
181 // It is also encoded as two analogs: 8 (X, -1 left 1 right) and
182 // 9 (Y, -1 up 1 down).
183 switch (buffer[3]) {
184 case 0:
185 buttons[16] = 1;
186 buttons[17] = 0;
187 buttons[18] = 0;
188 buttons[19] = 0;
189 channel[8] = 0;
190 channel[9] = -1;
191 break;
192
193 case 1:
194 buttons[16] = 1;
195 buttons[17] = 1;
196 buttons[18] = 0;
197 buttons[19] = 0;
198 channel[8] = 1;
199 channel[9] = -1;
200 break;
201
202 case 2:
203 buttons[16] = 0;
204 buttons[17] = 1;
205 buttons[18] = 0;
206 buttons[19] = 0;
207 channel[8] = 1;
208 channel[9] = 0;
209 break;
210
211 case 3:
212 buttons[16] = 0;
213 buttons[17] = 1;
214 buttons[18] = 1;
215 buttons[19] = 0;
216 channel[8] = 1;
217 channel[9] = 1;
218 break;
219
220 case 4:
221 buttons[16] = 0;
222 buttons[17] = 0;
223 buttons[18] = 1;
224 buttons[19] = 0;
225 channel[8] = 0;
226 channel[9] = 1;
227 break;
228
229 case 5:
230 buttons[16] = 0;
231 buttons[17] = 0;
232 buttons[18] = 1;
233 buttons[19] = 1;
234 channel[8] = -1;
235 channel[9] = 1;
236 break;
237
238 case 6:
239 buttons[16] = 0;
240 buttons[17] = 0;
241 buttons[18] = 0;
242 buttons[19] = 1;
243 channel[8] = -1;
244 channel[9] = 0;
245 break;
246
247 case 7:
248 buttons[16] = 1;
249 buttons[17] = 0;
250 buttons[18] = 0;
251 buttons[19] = 1;
252 channel[8] = -1;
253 channel[9] = -1;
254 break;
255
256 default:
257 buttons[16] = 0;
258 buttons[17] = 0;
259 buttons[18] = 0;
260 buttons[19] = 0;
261 channel[8] = 0;
262 channel[9] = 0;
263 break;
264 }
265
266 // Left stick X axis is bytes 4-5, least byte first, FF 7F in middle
267 // 00 00 to left, FF FF to right
268 // Left stick Y axis is bytes 6-7, 00 00 is up and FF FF is down
269 // Right stick X axis is bytes 8-9, 00 00 is left
270 // Right stick Y axis is bytes 10-11, 00 00 is up
271 int first_joy_axis = 4;
272 int num_joy_axis = 4;
273 int first_analog = 0;
274 vrpn_uint8 *bufptr = &buffer[4];
275 for (int axis = first_joy_axis; axis < first_joy_axis + num_joy_axis; axis++) {
276 vrpn_uint16 raw_val = vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr);
277 vrpn_int32 signed_val = raw_val - static_cast<int>(32767);
278 double value = signed_val / 32768.0;
279 channel[first_analog + axis - first_joy_axis] = value;
280 }
281
282 // Left analog finger trigger is bytes 12-13, 00 00 is out, FF FF is in
283 // Right analog finger trigger is bytes 14-15, 00 00 is out, FF FF is in
284 int first_trigger = 4;
285 int num_trigger = 2;
286 first_analog = 4;
287 bufptr = &buffer[12];
288 for (int trig = first_trigger; trig < first_trigger + num_trigger; trig++) {
289 vrpn_uint16 raw_val = vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr);
290 double value = raw_val / 65535.0;
291 channel[first_analog + trig - first_trigger] = value;
292 }
293
294 } else {
295 vrpn_uint8 type = 0;
296 if (bytes > 0) { type = buffer[0]; }
297 fprintf(stderr, "vrpn_nVidia_shield_USB: Unrecognized report type (%u); # total bytes = %u\n", type, static_cast<unsigned>(bytes));
298 }
299
300}
301
303 : vrpn_nVidia_shield(new vrpn_HidProductAcceptor(NVIDIA_VENDOR, NVIDIA_SHIELD_STEALTH_USB), name, c, NVIDIA_VENDOR, NVIDIA_SHIELD_STEALTH_USB)
304 , vrpn_Analog(name, c)
305 , vrpn_Button_Filter(name, c)
306{
309
310 // Initialize the state of all the analogs and buttons
311 memset(buttons, 0, sizeof(buttons));
312 memset(lastbuttons, 0, sizeof(lastbuttons));
313 memset(channel, 0, sizeof(channel));
314 memset(last, 0, sizeof(last));
315}
316
318{
319 update();
321 struct timeval current_time;
322 vrpn_gettimeofday(&current_time, NULL);
323 if (vrpn_TimevalDuration(current_time, d_timestamp) > POLL_INTERVAL ) {
324 d_timestamp = current_time;
326
327 // Call the server_mainloop on our unique base class.
329 }
330}
331
332void vrpn_nVidia_shield_stealth_USB::report(vrpn_uint32 class_of_service) {
334 {
336 }
338 {
340 }
341
343 {
344 vrpn_Analog::report(class_of_service);
345 }
347 {
349 }
350}
351
352void vrpn_nVidia_shield_stealth_USB::report_changes(vrpn_uint32 class_of_service) {
354 {
356 }
358 {
360 }
361
363 {
364 vrpn_Analog::report_changes(class_of_service);
365 }
367 {
369 }
370}
371
372void vrpn_nVidia_shield_stealth_USB::decodePacket(size_t bytes, vrpn_uint8 *buffer)
373{
374 // There is one type of report, type 1 is 32 bytes long (plus the
375 // type byte). On Windows, the packet is 232 bytes long (plus the
376 // type byte).
377
378 if ( (bytes >= 33) && (buffer[0] == 1) ) {
379
380 // 32-byte reports.
381 // Byte 0 is 01 (report type 1)
382 // Byte 1 is a counter index on reports that loops
383
384 // Byte 3:
385 // Bit 0: A button
386 // Bit 1: B button
387 // Bit 2: X button
388 // Bit 3: Y button
389 // Bit 4: Left finger trigger button
390 // Bit 5: Right finger trigger button
391 // Bit 6: Left joystick button
392 // Bit 7: Right joystick button
393
394 int first_byte = 3;
395 int num_bytes = 1;
396 int first_button = 0;
397 for (int byte = first_byte; byte < first_byte + num_bytes; byte++) {
398 vrpn_uint8 value = buffer[byte];
399 for (int btn = 0; btn < 8; btn++) {
400 vrpn_uint8 mask = static_cast<vrpn_uint8>(1 << btn);
401 buttons[8*(byte - first_byte) + btn + first_button] = ((value & mask) != 0);
402 }
403 }
404
405 // Byte 4:
406 // Bit 0: Play/pause button
407 buttons[9] = buffer[4] & 0x01;
408
409 // Byte 17:
410 // Bit 0: Circle button pressed
411 // Bit 1: Left-arrow button pressed
412 // Bit 2: Shield emblem pressed
413 buttons[12] = buffer[17] & 0x01;
414 buttons[11] = buffer[17] & 0x02;
415 buttons[13] = buffer[17] & 0x04;
416
417 // Byte 2: Left hi-hat:
418 // 80: Nothing pressed
419 // 0 = North, 1 = NE, 2 = E, 3 = SE, 4 = S, 5 = SW, 6 = W, 7 = NW
420 // This is encoded as buttons 16 (up), 17 (right), 18 (down), and 19 (left)
421 // It is also encoded as two analogs: 8 (X, -1 left 1 right) and
422 // 9 (Y, -1 up 1 down).
423 switch (buffer[2]) {
424 case 0:
425 buttons[16] = 1;
426 buttons[17] = 0;
427 buttons[18] = 0;
428 buttons[19] = 0;
429 channel[8] = 0;
430 channel[9] = -1;
431 break;
432
433 case 1:
434 buttons[16] = 1;
435 buttons[17] = 1;
436 buttons[18] = 0;
437 buttons[19] = 0;
438 channel[8] = 1;
439 channel[9] = -1;
440 break;
441
442 case 2:
443 buttons[16] = 0;
444 buttons[17] = 1;
445 buttons[18] = 0;
446 buttons[19] = 0;
447 channel[8] = 1;
448 channel[9] = 0;
449 break;
450
451 case 3:
452 buttons[16] = 0;
453 buttons[17] = 1;
454 buttons[18] = 1;
455 buttons[19] = 0;
456 channel[8] = 1;
457 channel[9] = 1;
458 break;
459
460 case 4:
461 buttons[16] = 0;
462 buttons[17] = 0;
463 buttons[18] = 1;
464 buttons[19] = 0;
465 channel[8] = 0;
466 channel[9] = 1;
467 break;
468
469 case 5:
470 buttons[16] = 0;
471 buttons[17] = 0;
472 buttons[18] = 1;
473 buttons[19] = 1;
474 channel[8] = -1;
475 channel[9] = 1;
476 break;
477
478 case 6:
479 buttons[16] = 0;
480 buttons[17] = 0;
481 buttons[18] = 0;
482 buttons[19] = 1;
483 channel[8] = -1;
484 channel[9] = 0;
485 break;
486
487 case 7:
488 buttons[16] = 1;
489 buttons[17] = 0;
490 buttons[18] = 0;
491 buttons[19] = 1;
492 channel[8] = -1;
493 channel[9] = -1;
494 break;
495
496 default:
497 buttons[16] = 0;
498 buttons[17] = 0;
499 buttons[18] = 0;
500 buttons[19] = 0;
501 channel[8] = 0;
502 channel[9] = 0;
503 break;
504 }
505
506 // Bytes 9 and 10 are a 16-bit left-joystick X axis analog, byte 10 MSB
507 // 00 00 to the left, ff ff to the right, around 00 80 centered
508 // Bytes 11 and 12 are a 16-bit left-joystick Y axis analog, byte 12 MSB
509 // 00 00 up, ff ff down, around 00 80 centered
510 // Bytes 13 and 14 are a 16-bit right-joystick X axis analog, byte 14 MSB
511 // 00 00 to the left, ff ff to the right, around 00 80 centered
512 // Bytes 15 and 16 are a 16-bit right-joystick Y axis analog, byte 16 MSB
513 // 00 00 up, ff ff down, around 00 80 centered
514 int first_joy_axis = 0;
515 int num_joy_axis = 4;
516 int first_analog = 0;
517 vrpn_uint8 *bufptr = &buffer[9];
518 for (int axis = first_joy_axis; axis < first_joy_axis + num_joy_axis; axis++) {
519 vrpn_uint16 raw_val = vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr);
520 vrpn_int32 signed_val = raw_val - static_cast<int>(32767);
521 double value = signed_val / 32768.0;
522 channel[first_analog + axis - first_joy_axis] = value;
523 }
524
525 // Bytes 5 and 6 are a 16-bit left-finger analog, byte 6 MSB
526 // Bytes 7 and 8 are a 16-bit right-finger analog, byte 8 MSB
527 int first_trigger = 0;
528 int num_trigger = 2;
529 first_analog = 4;
530 bufptr = &buffer[5];
531 for (int trig = first_trigger; trig < first_trigger + num_trigger; trig++) {
532 vrpn_uint16 raw_val = vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr);
533 double value = raw_val / 65535.0;
534 channel[first_analog + trig - first_trigger] = value;
535 }
536
537 } else {
538 vrpn_uint8 type = 0;
539 if (bytes > 0) { type = buffer[0]; }
540 fprintf(stderr, "vrpn_nVidia_shield_stealth_USB: Unrecognized report type (%u); # total bytes = %u\n", type, static_cast<unsigned>(bytes));
541 }
542
543}
544
545// End of VRPN_USE_HID
546#endif
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:39
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
struct timeval timestamp
Definition vrpn_Analog.h:41
vrpn_int32 num_channel
Definition vrpn_Analog.h:40
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition vrpn_Analog.C:94
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition vrpn_Analog.C:71
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition vrpn_Button.h:66
virtual void report_changes(void)
vrpn_int32 num_buttons
Definition vrpn_Button.h:48
struct timeval timestamp
Definition vrpn_Button.h:49
virtual void report_changes(void)
unsigned char lastbuttons[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:46
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:45
Generic connection class not specific to the transport mechanism.
virtual void update()
Polls the device buffers and causes on_data_received callbacks if appropriate You NEED to call this f...
Accepts any device with the given vendor and product IDs.
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
vrpn_nVidia_shield_USB(const char *name, vrpn_Connection *c=0)
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
vrpn_nVidia_shield_stealth_USB(const char *name, vrpn_Connection *c=0)
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
virtual void decodePacket(size_t bytes, vrpn_uint8 *buffer)=0
vrpn_nVidia_shield(vrpn_HidAcceptor *filter, const char *name, vrpn_Connection *c=0, vrpn_uint16 vendor=0, vrpn_uint16 product=0)
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Derived class reimplements this callback.
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
#define POLL_INTERVAL
Definition vrpn_IDEA.C:26
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99