10#if defined(VRPN_USE_HID)
15static const vrpn_uint16 RETROLINK_VENDOR = 0x0079;
16static const vrpn_uint16 RETROLINK_GAMECUBE = 0x0006;
17static const vrpn_uint16 RETROLINK_GENESIS = 0x0011;
23static vrpn_float64 normalize_axis(
const vrpn_uint8 value)
25 vrpn_float64 offset =
static_cast<vrpn_float64
>(value) - 128;
26 vrpn_float64 scaled = offset / 127;
27 if (scaled > 1) { scaled = 1; }
28 if (scaled < -1) { scaled = -1; }
33static void angle_and_buttons_from_rocker_byte(
const vrpn_uint8 value,
35 bool *up,
bool *right,
bool *down,
bool *left)
38 case 0: *angle = 0; *up =
true; *right =
false; *down =
false; *left =
false;
break;
39 case 1: *angle = 45; *up =
true; *right =
true; *down =
false; *left =
false;
break;
40 case 2: *angle = 90; *up =
false; *right =
true; *down =
false; *left =
false;
break;
41 case 3: *angle = 135; *up =
false; *right =
true; *down =
true; *left =
false;
break;
42 case 4: *angle = 180; *up =
false; *right =
false; *down =
true; *left =
false;
break;
43 case 5: *angle = 225; *up =
false; *right =
false; *down =
true; *left =
true;
break;
44 case 6: *angle = 270; *up =
false; *right =
false; *down =
false; *left =
true;
break;
45 case 7: *angle = 315; *up =
true; *right =
false; *down =
false; *left =
true;
break;
46 default: *angle = -1; *up =
false; *right =
false; *down =
false; *left =
false;
break;
51static void angle_and_buttons_from_rocker_doublet(
52 const vrpn_uint8 value0,
const vrpn_uint8 value1,
54 bool *up,
bool *right,
bool *down,
bool *left)
60 case 0x00: value = 7;
break;
61 case 0x7F: value = 6;
break;
62 case 0xFF: value = 5;
break;
68 case 0x00: value = 0;
break;
69 case 0x7F: value = 8;
break;
70 case 0xFF: value = 4;
break;
76 case 0x00: value = 1;
break;
77 case 0x7F: value = 2;
break;
78 case 0xFF: value = 3;
break;
82 angle_and_buttons_from_rocker_byte(value, angle, up, right, down, left);
86 vrpn_uint16 vendor, vrpn_uint16 product)
99 fprintf(stderr,
"vrpn_Retrolink::~vrpn_Retrolink(): delete failed\n");
143 struct timeval current_time;
229 channel[0] = normalize_axis(buffer[0]);
230 channel[1] = normalize_axis(buffer[1]);
231 channel[2] = normalize_axis(buffer[3]);
232 channel[3] = normalize_axis(buffer[4]);
235 buttons[0] = (buffer[5] & (1 << 4)) != 0;
236 buttons[1] = (buffer[5] & (1 << 5)) != 0;
237 buttons[2] = (buffer[5] & (1 << 6)) != 0;
238 buttons[3] = (buffer[5] & (1 << 7)) != 0;
239 buttons[4] = (buffer[6] & (1 << 0)) != 0;
240 buttons[5] = (buffer[6] & (1 << 1)) != 0;
241 buttons[6] = (buffer[6] & (1 << 2)) != 0;
242 buttons[7] = (buffer[6] & (1 << 5)) != 0;
245 vrpn_uint8 rocker = buffer[5] & 0x0f;
247 bool up, right, down, left;
248 angle_and_buttons_from_rocker_byte(rocker, &angle, &up, &right, &down, &left);
254 fprintf(stderr,
"vrpn_Retrolink_GameCube: Found a corrupted report; # total bytes = %u\n",
static_cast<unsigned>(bytes));
276 struct timeval current_time;
352 buttons[0] = (buffer[5] & (1 << 6)) != 0;
353 buttons[1] = (buffer[5] & (1 << 5)) != 0;
354 buttons[2] = (buffer[6] & (1 << 1)) != 0;
355 buttons[3] = (buffer[5] & (1 << 7)) != 0;
356 buttons[4] = (buffer[5] & (1 << 4)) != 0;
357 buttons[5] = (buffer[6] & (1 << 0)) != 0;
358 buttons[6] = (buffer[6] & (1 << 4)) != 0;
359 buttons[7] = (buffer[6] & (1 << 5)) != 0;
362 vrpn_uint8 rocker0 = buffer[3];
363 vrpn_uint8 rocker1 = buffer[4];
365 bool up, right, down, left;
366 angle_and_buttons_from_rocker_doublet(rocker0, rocker1,
367 &angle, &up, &right, &down, &left);
374 fprintf(stderr,
"vrpn_Retrolink_Genesis: Found a corrupted report; # total bytes = %u\n",
static_cast<unsigned>(bytes));
vrpn_float64 channel[vrpn_CHANNEL_MAX]
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 ...
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Connection * d_connection
Connection that this object talks to.
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...
Generic connection class not specific to the transport mechanism.
virtual vrpn_int32 register_message_type(const char *name)
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.
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
vrpn_Retrolink_GameCube(const char *name, vrpn_Connection *c=0)
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Retrolink_Genesis(const char *name, vrpn_Connection *c=0)
virtual void decodePacket(size_t bytes, vrpn_uint8 *buffer)=0
virtual ~vrpn_Retrolink(void)
vrpn_Retrolink(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.
static int VRPN_CALLBACK on_connect(void *thisPtr, vrpn_HANDLERPARAM p)
struct timeval _timestamp
static int VRPN_CALLBACK on_last_disconnect(void *thisPtr, vrpn_HANDLERPARAM p)
vrpn_HidAcceptor * _filter
This structure is what is passed to a vrpn_Connection message callback.
const char * vrpn_dropped_last_connection
const char * vrpn_got_connection
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
#define vrpn_gettimeofday