Preparations for Xbox360 wireless support
This commit is contained in:
parent
b07cf7f2be
commit
aeea6bf669
16 changed files with 1001 additions and 271 deletions
306
PROTOCOL
Normal file
306
PROTOCOL
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
===========================
|
||||||
|
[[ Protocol Descriptions ]]
|
||||||
|
===========================
|
||||||
|
|
||||||
|
General:
|
||||||
|
========
|
||||||
|
|
||||||
|
The following was learned through a combination of guessing and
|
||||||
|
looking at the Windows, MacOSX and Linux Kernel drivers. No gurantee
|
||||||
|
for correctness.
|
||||||
|
|
||||||
|
Use usb_interrupt_read() not usb_bulk_read(), the later one fails with
|
||||||
|
the Xbox360 guitar.
|
||||||
|
|
||||||
|
Xbox:
|
||||||
|
=====
|
||||||
|
|
||||||
|
The A, B, X, Y, black and white buttons on the Xbox pad are 8bit pressure sensitive.
|
||||||
|
|
||||||
|
Led: doesn't have LEDs
|
||||||
|
Rumble: { 0x00, 0x06, 0x00, l, 0x00, b };
|
||||||
|
^-- length of the message
|
||||||
|
|
||||||
|
struct XboxMsg
|
||||||
|
{
|
||||||
|
// --------------------------
|
||||||
|
unsigned int type :8;
|
||||||
|
unsigned int length :8;
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1;
|
||||||
|
unsigned int dpad_down :1;
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1;
|
||||||
|
unsigned int thumb_r :1;
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int dummy :8;
|
||||||
|
unsigned int a :8;
|
||||||
|
unsigned int b :8;
|
||||||
|
unsigned int x :8;
|
||||||
|
unsigned int y :8;
|
||||||
|
unsigned int black :8;
|
||||||
|
unsigned int white :8;
|
||||||
|
unsigned int lt :8;
|
||||||
|
unsigned int rt :8;
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16;
|
||||||
|
int y1 :16;
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int x2 :16;
|
||||||
|
int y2 :16;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
|
||||||
|
Xbox360 Controller
|
||||||
|
==================
|
||||||
|
|
||||||
|
The Xbox360 controller doesn't have pressure sensitive A,B,X,Y,LB,RB
|
||||||
|
buttons like the Xbox controller, only LT and RT are analog.
|
||||||
|
|
||||||
|
On first connect the controller sends:
|
||||||
|
|
||||||
|
len: 3 data: 0x01 0x03 0x0e
|
||||||
|
len: 3 data: 0x02 0x03 0x00
|
||||||
|
len: 3 data: 0x03 0x03 0x03
|
||||||
|
len: 3 data: 0x08 0x03 0x00
|
||||||
|
len: 20 data: 0x00 0x14 0x00 0x00 0x00 0x00 0x69 0xed 0x23 0xff 0x6b 0x00 0x15 0x03 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 20 data: 0x00 0x14 0x00 0x00 0x00 0x00 0xfc 0xec 0x23 0xff 0x6b 0x00 0x15 0x03 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
The first four lines are unknown (guess: calibration data, serial
|
||||||
|
number, version number?), but seem to be always the same, the "len: 20" ones are event
|
||||||
|
data of the following form. The controller sends them two times on
|
||||||
|
each button press and also two times on first connect.
|
||||||
|
|
||||||
|
Commands send to the controller:
|
||||||
|
--------------------------------
|
||||||
|
,--------- type of message
|
||||||
|
v v-- length of message
|
||||||
|
LED: { 0x01, 0x03, LED_STATUS };
|
||||||
|
Rumble: { 0x00, 0x08, 0x00, large, small, 0x00, 0x00, 0x00 };
|
||||||
|
^ ^-- length of the message
|
||||||
|
`--------- type of message
|
||||||
|
|
||||||
|
struct Xbox360Msg
|
||||||
|
{
|
||||||
|
// -------------------------
|
||||||
|
unsigned int type :8; // always 0
|
||||||
|
unsigned int length :8; // always 0x14
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1;
|
||||||
|
unsigned int dpad_down :1;
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1;
|
||||||
|
unsigned int thumb_r :1;
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int lb :1;
|
||||||
|
unsigned int rb :1;
|
||||||
|
unsigned int guide :1;
|
||||||
|
unsigned int dummy1 :1; // always 0
|
||||||
|
|
||||||
|
unsigned int a :1;
|
||||||
|
unsigned int b :1;
|
||||||
|
unsigned int x :1;
|
||||||
|
unsigned int y :1;
|
||||||
|
|
||||||
|
// data[4] ------------------
|
||||||
|
unsigned int lt :8;
|
||||||
|
unsigned int rt :8;
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16;
|
||||||
|
int y1 :16;
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int x2 :16;
|
||||||
|
int y2 :16;
|
||||||
|
|
||||||
|
// data[14]; ----------------
|
||||||
|
unsigned int dummy2 :32; // always 0
|
||||||
|
unsigned int dummy3 :16; // always 0
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
Xbox360 Guitar
|
||||||
|
==============
|
||||||
|
|
||||||
|
The Xbox360 Guitar behaves the same as a regular Xbox360 controller
|
||||||
|
and talks the same protocol just with the meaning of a few buttons and
|
||||||
|
axis changed. The guitar doesn't have rumble support.
|
||||||
|
|
||||||
|
struct Xbox360GuitarMsg
|
||||||
|
{
|
||||||
|
// -------------------------
|
||||||
|
unsigned int type :8;
|
||||||
|
unsigned int length :8;
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1; // also strum-up
|
||||||
|
unsigned int dpad_down :1; // also strum-down
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1; // unused
|
||||||
|
unsigned int thumb_r :1; // unused
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int orange :1; // 5
|
||||||
|
unsigned int rb :1; // unused
|
||||||
|
unsigned int guide :1;
|
||||||
|
unsigned int dummy1 :1; // unused
|
||||||
|
|
||||||
|
unsigned int green :1; // 1, A
|
||||||
|
unsigned int red :1; // 2, B
|
||||||
|
unsigned int blue :1; // 4, X
|
||||||
|
unsigned int yellow :1; // 3, Y
|
||||||
|
|
||||||
|
// data[4] ------------------
|
||||||
|
unsigned int lt :8; // unknown
|
||||||
|
unsigned int rt :8; // unknown
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16; // unused
|
||||||
|
int y1 :16; // unused
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int whammy :16;
|
||||||
|
int tilt :16;
|
||||||
|
|
||||||
|
// data[14]; ----------------
|
||||||
|
unsigned int dummy2 :32; // unused
|
||||||
|
unsigned int dummy3 :16; // unused
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
Xbox360 Wireless
|
||||||
|
================
|
||||||
|
|
||||||
|
Endpoint 1: Controller 1
|
||||||
|
Endpoint 2: Headset 1
|
||||||
|
Endpoint 3: Controller 1
|
||||||
|
Endpoint 4: Headset 1
|
||||||
|
Endpoint 5: Controller 1
|
||||||
|
Endpoint 6: Headset 1
|
||||||
|
Endpoint 7: Controller 4
|
||||||
|
Endpoint 8: Headset 1
|
||||||
|
v-- typo? might be 0x0c, i.e. length
|
||||||
|
Rumble: { 0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||||
|
^ ^--- ???
|
||||||
|
+--------- seems the same as in Event Data
|
||||||
|
LED: { 0x00, 0x00, 0x08, 0x40 + (mode % 0x0e), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||||
|
|
||||||
|
|
||||||
|
On connection:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
len: 2 data: 0x08 0x80
|
||||||
|
len: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xa7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
len: 29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
Different connection:
|
||||||
|
---------------------
|
||||||
|
|||| |||| |||| |||| |||| |||| |||| _________________ Serial?_________ |||| |||| |||| _____ Battery?
|
||||||
|
29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd[0x55 0x40 0xf0 0x48 0xe4 0x5d 0x10]0x00 0x05 0x13[0x67]0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
len: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xe7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
len: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xa7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
|
||||||
|
When the controller connects it sends { 0x08 0x80 } -> 0000'1000 1000'0000
|
||||||
|
When the headset connects it sends: { 0x08 0xc0 } -> 0000'1000 1100'0000
|
||||||
|
When nothing is connected: { 0x08 0x00 } -> 0000'1000 0000'0000
|
||||||
|
|
||||||
|
Event data:
|
||||||
|
===========
|
||||||
|
+-------- always 0
|
||||||
|
| +---- 0x01 when a event message, 0x00 otherwise (battery status?), also 0xf8 and 0x0f (both on new connection)
|
||||||
|
| | +--- always 0xf0 (1111'0000)
|
||||||
|
| | |
|
||||||
|
| | | +-- length
|
||||||
|
v v v v v---- normal xbox event message, but one byte shorter + 5x 0x00 padding
|
||||||
|
len: 29 data: 0x00 0x01 0x00 0xf0 0x00 0x13 0x20 0x00 0x00 0x00 0xc1 0x08 0xc9 0xfc 0x67 0xf4 0xe5 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x01 0x00 0xf0 0x00 0x13 0x00 0x00 0x00 0x00 0xc1 0x08 0xc9 0xfc 0x67 0xf4 0xe5 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
|
||||||
|
Battery Status Msg (maybe):
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
len: 29 data: 0x00 0xf8 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
Battery Full(?):
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
Controller without doing anything
|
||||||
|
2 data: 0x08 0x80
|
||||||
|
29 data: 0x00 0x00 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
____ battery ?
|
||||||
|
29 data: 0x00 0x00 0x00 0x13 0xe2 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
29 data: 0x00 0x00 0x00 0x13 0xe6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
29 data: 0x00 0x00 0x00 0x20 0x1d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
29 data: 0x00 0x00 0x00 0x40 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
29 data: 0x00 0x00 0x00 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xe7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
---------------
|
||||||
|
len: 29 data: 0x00 0x01 0x00 0xf0 0x00 0x13 0x00 0x00 0x00 0x00 0x94 0xff 0xc0 0x02 0xa6 0x02 0xf0 0xf6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x01 0x00 0xf0 0x00 0x13 0x00 0x00 0x00 0x00 0x14 0xfd 0xc0 0x02 0xa6 0x02 0xf0 0xf6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
Battery Message?:
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x13 0xa2 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x13 0xe2 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x13 0xe6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
// Charging?
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x13 0xe0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
Unknown:
|
||||||
|
len: 29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x20 0x1d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0x40 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0x00 0x00 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
len: 29 data: 0x00 0x01 0x00 0x13 0xa6 0x13 0x00 0x00 0x00 0x00 0xa9 0xfc 0x60 0x01 0x9d 0x00 0x61 0xf7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - similar to normal event message
|
||||||
|
|
||||||
|
Init message
|
||||||
|
__________________________________ ____
|
||||||
|
len: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xa7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
len: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x1f 0x9f 0x70 0xc9 0x00 0x63 0xb0 0x00 0x05 0x13 0xe7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
C1n: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x55 0x40 0xf0 0x47 0xee 0x1a 0xb0 0x00 0x05 0x13 0xe1 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
C2n: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x55 0x40 0xf0 0x48 0xe4 0x5d 0x10 0x00 0x05 0x13 0xa7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
C3n: 29 data: 0x00 0x0f 0x00 0xf0 0xf0 0xcc 0xfd 0x55 0x40 0xf0 0x47 0x06 0x87 0xc0 0x00 0x05 0x13 0xa7 0x20 0x1d 0x30 0x03 0x40 0x01 0x50 0x01 0xff 0xff 0xff
|
||||||
|
|
||||||
|
len: 29 data: 0x00 0xf8 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 28 data: 0x00 0x01 0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
# Request power-off?
|
||||||
|
len: 29 data: 0x00 0xf8 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
len: 29 data: 0x00 0xf8 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||||
|
|
||||||
|
# EOF #
|
|
@ -1,12 +1,14 @@
|
||||||
# -*- python -*-
|
# -*- python -*-
|
||||||
|
|
||||||
env = Environment(CPPFLAGS=["-g", "-O0", "-Wall"], LIBS=["usb"])
|
env = Environment(CPPFLAGS=["-g", "-O0", "-Wall"], LIBS=["usb"])
|
||||||
env.Program("xboxdrv", ["xboxdrv.cpp", "uinput.cpp"])
|
env.Program("xboxdrv", ["xboxdrv.cpp", "xboxmsg.cpp", "uinput.cpp"])
|
||||||
env.Program("inputdrv",
|
env.Program("inputdrv",
|
||||||
["inputdrv.cpp",
|
["inputdrv.cpp",
|
||||||
"xbox360_driver.cpp",
|
"xbox360_driver.cpp",
|
||||||
"evdev_driver.cpp",
|
"evdev_driver.cpp",
|
||||||
"xbox360_usb_thread.cpp",
|
"xbox360_usb_thread.cpp",
|
||||||
|
"xbox360_controller.cpp",
|
||||||
|
"xbox360_wireless_controller.cpp",
|
||||||
"control.cpp",
|
"control.cpp",
|
||||||
"abs_to_rel.cpp",
|
"abs_to_rel.cpp",
|
||||||
"abs_to_btn.cpp",
|
"abs_to_btn.cpp",
|
||||||
|
|
15
TODO
15
TODO
|
@ -1,3 +1,16 @@
|
||||||
|
Easy interface:
|
||||||
|
===============
|
||||||
|
--trigger-as-zaxis
|
||||||
|
--
|
||||||
|
--buttonmap A:B,B:B,X:X
|
||||||
|
|
||||||
|
Controller 1:
|
||||||
|
Data 2: 0x08 0x80
|
||||||
|
|
||||||
|
Controller 2:
|
||||||
|
Data 2: 0x08 0xc0
|
||||||
|
|
||||||
|
|
||||||
* a way to send keyboard combination sequences or more general event sequences
|
* a way to send keyboard combination sequences or more general event sequences
|
||||||
* abs input must be normalized to min/max
|
* abs input must be normalized to min/max
|
||||||
* rel input must be scaleable
|
* rel input must be scaleable
|
||||||
|
@ -82,7 +95,7 @@ Unknown data: bytes: 3 Data: 0x01 0x03 0x00
|
||||||
|
|
||||||
|
|
||||||
// wire: { 0x00, 0x08, 0x00, large, small, 0x00, 0x00, 0x00 };
|
// wire: { 0x00, 0x08, 0x00, large, small, 0x00, 0x00, 0x00 };
|
||||||
// wireless: { 0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00};
|
// wireless: { 0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
^^^^ typo?
|
^^^^ typo?
|
||||||
void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char small)
|
void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char small)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,13 +22,14 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/uinput.h>
|
#include <linux/uinput.h>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
#include "uinput.hpp"
|
#include "uinput.hpp"
|
||||||
|
|
||||||
uInput::uInput(GamepadType type, uInputCfg config_)
|
uInput::uInput(GamepadType type, uInputCfg config_)
|
||||||
: fd(-1), config(config_)
|
: fd(-1), config(config_)
|
||||||
{
|
{
|
||||||
// Open the input device
|
// Open the input device
|
||||||
char* uinput_filename[] = { "/dev/input/uinput", "/dev/uinput", "/dev/misc/uinput" };
|
const char* uinput_filename[] = { "/dev/input/uinput", "/dev/uinput", "/dev/misc/uinput" };
|
||||||
const int uinput_filename_count = (sizeof(uinput_filename)/sizeof(char*));
|
const int uinput_filename_count = (sizeof(uinput_filename)/sizeof(char*));
|
||||||
|
|
||||||
for (int i = 0; i < uinput_filename_count; ++i)
|
for (int i = 0; i < uinput_filename_count; ++i)
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
#include "xboxdrv.hpp"
|
#include "xboxdrv.hpp"
|
||||||
|
|
||||||
|
class Xbox360Msg;
|
||||||
|
class Xbox360GuitarMsg;
|
||||||
|
class XboxMsg;
|
||||||
|
|
||||||
class uInputCfg
|
class uInputCfg
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
85
xbox360_controller.cpp
Normal file
85
xbox360_controller.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
|
#include "xbox360_controller.hpp"
|
||||||
|
|
||||||
|
Xbox360Controller::Xbox360Controller(struct usb_device* dev,
|
||||||
|
XPadDevice* dev_type)
|
||||||
|
{
|
||||||
|
struct usb_dev_handle* handle = usb_open(dev);
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Error opening Xbox360 controller");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (usb_claim_interface(handle, 0) != 0) // FIXME: bInterfaceNumber shouldn't be hardcoded
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Error couldn't claim the USB interface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360Controller::set_rumble(uint8_t left, uint8_t right)
|
||||||
|
{
|
||||||
|
char rumblecmd[] = { 0x00, 0x08, 0x00, left, right, 0x00, 0x00, 0x00 };
|
||||||
|
usb_interrupt_write(handle, 2, rumblecmd, 8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360Controller::set_led(uint8_t status)
|
||||||
|
{
|
||||||
|
char ledcmd[] = { 1, 3, status };
|
||||||
|
usb_interrupt_write(handle, 2, ledcmd, sizeof(ledcmd), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360Controller::read(Xbox360Msg& msg)
|
||||||
|
{
|
||||||
|
uint8_t data[32];
|
||||||
|
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{ // Error
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "USBError: " << ret << "\n" << usb_strerror();
|
||||||
|
throw std::runtime_error(str.str());
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
// happens with the Xbox360 controller every now and then, just
|
||||||
|
// ignore, seems harmless, so just ignore
|
||||||
|
}
|
||||||
|
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
|
||||||
|
{
|
||||||
|
msg = (Xbox360Msg&)data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
56
xbox360_controller.hpp
Normal file
56
xbox360_controller.hpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_XBOX360_CONTROLLER_HPP
|
||||||
|
#define HEADER_XBOX360_CONTROLLER_HPP
|
||||||
|
|
||||||
|
#include <usb.h>
|
||||||
|
|
||||||
|
struct XPadDevice;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
class Xbox360Controller
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct usb_device* dev;
|
||||||
|
XPadDevice* dev_type;
|
||||||
|
struct usb_dev_handle* handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Xbox360Controller(struct usb_device* dev,
|
||||||
|
XPadDevice* dev_type);
|
||||||
|
|
||||||
|
void set_rumble(uint8_t left, uint8_t right);
|
||||||
|
void set_led(uint8_t status);
|
||||||
|
void read(Xbox360Msg& msg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Xbox360Controller (const Xbox360Controller&);
|
||||||
|
Xbox360Controller& operator= (const Xbox360Controller&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -29,6 +29,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "xbox360_usb_thread.hpp"
|
#include "xbox360_usb_thread.hpp"
|
||||||
#include "xbox360_driver.hpp"
|
#include "xbox360_driver.hpp"
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "control.hpp"
|
#include "control.hpp"
|
||||||
|
|
||||||
class Xbox360UsbThread;
|
class Xbox360UsbThread;
|
||||||
|
class Xbox360Msg;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
class Xbox360Driver : public Control
|
class Xbox360Driver : public Control
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
#include "xbox360_usb_thread.hpp"
|
#include "xbox360_usb_thread.hpp"
|
||||||
|
|
||||||
Xbox360UsbThread::Xbox360UsbThread(struct usb_device* dev)
|
Xbox360UsbThread::Xbox360UsbThread(struct usb_device* dev)
|
||||||
|
|
139
xbox360_wireless_controller.cpp
Normal file
139
xbox360_wireless_controller.cpp
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <usb.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
|
#include "xbox360_wireless_controller.hpp"
|
||||||
|
|
||||||
|
Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev,
|
||||||
|
XPadDevice* dev_type,
|
||||||
|
int controller_id)
|
||||||
|
{
|
||||||
|
assert(controller_id >= 0 && controller_id < 4);
|
||||||
|
|
||||||
|
// FIXME: Is hardcoding those ok?
|
||||||
|
endpoint = controller_id*2 + 1;
|
||||||
|
interface = controller_id*2;
|
||||||
|
|
||||||
|
struct usb_dev_handle* handle = usb_open(dev);
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Xbox360WirelessController: Error opening Xbox360 controller");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (usb_claim_interface(handle, interface) != 0) // FIXME: bInterfaceNumber shouldn't be hardcoded
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Xbox360WirelessController: Error couldn't claim the USB interface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360WirelessController::set_rumble(uint8_t left, uint8_t right)
|
||||||
|
{
|
||||||
|
// +-- typo? might be 0x0c, i.e. length
|
||||||
|
// v
|
||||||
|
char rumblecmd[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, left, right, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
usb_interrupt_write(handle, endpoint, rumblecmd, sizeof(rumblecmd), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360WirelessController::set_led(uint8_t status)
|
||||||
|
{
|
||||||
|
// +--- Why not just status?
|
||||||
|
// v
|
||||||
|
char ledcmd[] = { 0x00, 0x00, 0x08, 0x40 + (status % 0x0e), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
usb_interrupt_write(handle, endpoint, ledcmd, sizeof(ledcmd), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Xbox360WirelessController::read(Xbox360Msg& msg)
|
||||||
|
{
|
||||||
|
uint8_t data[32];
|
||||||
|
int ret = usb_interrupt_read(handle, endpoint, (char*)data, sizeof(data), 0 /*Timeout*/);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{ // Error
|
||||||
|
std::ostringstream str;
|
||||||
|
str << "USBError: " << ret << "\n" << usb_strerror();
|
||||||
|
throw std::runtime_error(str.str());
|
||||||
|
}
|
||||||
|
else if (ret == 2 && data[0] == 0x08)
|
||||||
|
{ // Connection Status Message
|
||||||
|
if (data[1] == 0x00)
|
||||||
|
{
|
||||||
|
// nothing connected
|
||||||
|
}
|
||||||
|
else if (data[1] == 0x80)
|
||||||
|
{
|
||||||
|
// controller connected
|
||||||
|
}
|
||||||
|
else if (data[1] == 0x40)
|
||||||
|
{
|
||||||
|
// headset connected
|
||||||
|
}
|
||||||
|
else if (data[1] == 0xc0)
|
||||||
|
{
|
||||||
|
// headset and controller connected
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret == 29) // Event Message
|
||||||
|
{
|
||||||
|
if (data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0)
|
||||||
|
{ // Initial Announc Message
|
||||||
|
std::string serial = (boost::format("%x:%x:%x:%x:%x:%x")
|
||||||
|
% data[7] % data[8] % data[9] % data[10] % data[11] % data[12] % data[13]).str();
|
||||||
|
|
||||||
|
battery_status = data[17];
|
||||||
|
}
|
||||||
|
else if (data[0] == 0x00 && data[1] == 0x01 && data[2] == 0x00 && data[3] == 0xf0 && data[4] == 0x00 && data[5] == 0x13)
|
||||||
|
{
|
||||||
|
msg = *reinterpret_cast<Xbox360Msg*>(&data[6]);
|
||||||
|
}
|
||||||
|
else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13)
|
||||||
|
{ // Battery status
|
||||||
|
battery_status = data[4];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unknown/junk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unknown/junk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
59
xbox360_wireless_controller.hpp
Normal file
59
xbox360_wireless_controller.hpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_XBOX360_WIRELESS_CONTROLLER_HPP
|
||||||
|
#define HEADER_XBOX360_WIRELESS_CONTROLLER_HPP
|
||||||
|
|
||||||
|
struct XPadDevice;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
class Xbox360WirelessController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct usb_device* dev;
|
||||||
|
XPadDevice* dev_type;
|
||||||
|
struct usb_dev_handle* handle;
|
||||||
|
int endpoint;
|
||||||
|
int interface;
|
||||||
|
uint8_t battery_status;
|
||||||
|
std::string serial;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Xbox360WirelessController(struct usb_device* dev,
|
||||||
|
XPadDevice* dev_type,
|
||||||
|
int controller_id);
|
||||||
|
|
||||||
|
void set_rumble(uint8_t left, uint8_t right);
|
||||||
|
void set_led(uint8_t status);
|
||||||
|
void read(Xbox360Msg& msg);
|
||||||
|
uint8_t get_battery_status() const;
|
||||||
|
private:
|
||||||
|
Xbox360WirelessController (const Xbox360WirelessController&);
|
||||||
|
Xbox360WirelessController& operator= (const Xbox360WirelessController&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
159
xboxdrv.cpp
159
xboxdrv.cpp
|
@ -21,8 +21,8 @@
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "uinput.hpp"
|
#include "uinput.hpp"
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
#include "xboxdrv.hpp"
|
#include "xboxdrv.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,118 +101,6 @@ std::ostream& operator<<(std::ostream& out, const GamepadType& type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Xbox360GuitarMsg& msg)
|
|
||||||
{
|
|
||||||
out << boost::format(" whammy:%6d tilt:%6d | up:%d down:%d left:%d right:%d | back:%d guide:%d start:%d | green:%d red:%d yellow:%d blue:%d orange:%d ")
|
|
||||||
% int(msg.whammy)
|
|
||||||
% int(msg.tilt)
|
|
||||||
% int(msg.dpad_up)
|
|
||||||
% int(msg.dpad_down)
|
|
||||||
% int(msg.dpad_left)
|
|
||||||
% int(msg.dpad_right)
|
|
||||||
% int(msg.back)
|
|
||||||
% int(msg.guide)
|
|
||||||
% int(msg.start)
|
|
||||||
% int(msg.green)
|
|
||||||
% int(msg.red)
|
|
||||||
% int(msg.yellow)
|
|
||||||
% int(msg.blue)
|
|
||||||
% int(msg.orange);
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
out << boost::format("| dummy: %d %d %d %d %02hhx %02hhx %04hx %04hx %02x %02x")
|
|
||||||
% int(msg.thumb_l)
|
|
||||||
% int(msg.thumb_r)
|
|
||||||
% int(msg.rb)
|
|
||||||
% int(msg.dummy1)
|
|
||||||
|
|
||||||
% int(msg.lt)
|
|
||||||
% int(msg.rt)
|
|
||||||
|
|
||||||
% int16_t(msg.x1)
|
|
||||||
% int16_t(msg.y1)
|
|
||||||
|
|
||||||
% int(msg.dummy2)
|
|
||||||
% int(msg.dummy3);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Xbox360Msg& msg)
|
|
||||||
{
|
|
||||||
out << boost::format("S1:(%6d, %6d)")
|
|
||||||
% int(msg.x1) % int(msg.y1);
|
|
||||||
|
|
||||||
out << boost::format(" S2:(%6d, %6d)")
|
|
||||||
% int(msg.x2) % int(msg.y2);
|
|
||||||
|
|
||||||
out << boost::format(" [u:%d|d:%d|l:%d|r:%d]")
|
|
||||||
% int(msg.dpad_up)
|
|
||||||
% int(msg.dpad_down)
|
|
||||||
% int(msg.dpad_left)
|
|
||||||
% int(msg.dpad_right);
|
|
||||||
|
|
||||||
out << " back:" << msg.back;
|
|
||||||
out << " guide:" << msg.guide;
|
|
||||||
out << " start:" << msg.start;
|
|
||||||
|
|
||||||
out << " sl:" << msg.thumb_l;
|
|
||||||
out << " sr:" << msg.thumb_r;
|
|
||||||
|
|
||||||
out << " A:" << msg.a;
|
|
||||||
out << " B:" << msg.b;
|
|
||||||
out << " X:" << msg.x;
|
|
||||||
out << " Y:" << msg.y;
|
|
||||||
|
|
||||||
out << " LB:" << msg.lb;
|
|
||||||
out << " RB:" << msg.rb;
|
|
||||||
|
|
||||||
out << boost::format(" LT:%3d RT:%3d")
|
|
||||||
% int(msg.lt) % int(msg.rt);
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
out << " Dummy: " << msg.dummy1 << " " << msg.dummy2 << " " << msg.dummy3;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const XboxMsg& msg)
|
|
||||||
{
|
|
||||||
out << boost::format(" S1:(%6d, %6d) S2:(%6d, %6d) "
|
|
||||||
" [u:%d|d:%d|l:%d|r:%d] "
|
|
||||||
" start:%d back:%d "
|
|
||||||
" sl:%d sr:%d "
|
|
||||||
" A:%3d B:%3d X:%3d Y:%3d "
|
|
||||||
" black:%3d white:%3d "
|
|
||||||
" LT:%3d RT:%3d ")
|
|
||||||
% int(msg.x1) % int(msg.y1)
|
|
||||||
% int(msg.x2) % int(msg.y2)
|
|
||||||
|
|
||||||
% int(msg.dpad_up)
|
|
||||||
% int(msg.dpad_down)
|
|
||||||
% int(msg.dpad_left)
|
|
||||||
% int(msg.dpad_right)
|
|
||||||
|
|
||||||
% int(msg.start)
|
|
||||||
% int(msg.back)
|
|
||||||
|
|
||||||
% int(msg.thumb_l)
|
|
||||||
% int(msg.thumb_r)
|
|
||||||
|
|
||||||
% int(msg.a)
|
|
||||||
% int(msg.b)
|
|
||||||
% int(msg.x)
|
|
||||||
% int(msg.y)
|
|
||||||
|
|
||||||
% int(msg.black)
|
|
||||||
% int(msg.white)
|
|
||||||
|
|
||||||
% int(msg.lt)
|
|
||||||
% int(msg.rt);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void list_controller()
|
void list_controller()
|
||||||
{
|
{
|
||||||
struct usb_bus* busses = usb_get_busses();
|
struct usb_bus* busses = usb_get_busses();
|
||||||
|
@ -638,6 +526,20 @@ void parse_command_line(int argc, char** argv, CommandLineOptions& opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_info(struct usb_device* dev,
|
||||||
|
XPadDevice* dev_type,
|
||||||
|
const CommandLineOptions& opts)
|
||||||
|
{
|
||||||
|
std::cout << "USB Device: " << dev->bus->dirname << ":" << dev->filename << std::endl;
|
||||||
|
std::cout << "Controller: " << boost::format("\"%s\" (idVendor: 0x%04x, idProduct: 0x%04x)")
|
||||||
|
% (dev_type ? dev_type->name : "unknown") % uint16_t(dev->descriptor.idVendor) % uint16_t(dev->descriptor.idProduct) << std::endl;
|
||||||
|
std::cout << "Controller Type: " << opts.gamepad_type << std::endl;
|
||||||
|
std::cout << "Deadzone: " << opts.deadzone << std::endl;
|
||||||
|
std::cout << "Rumble Debug: " << (opts.rumble ? "on" : "off") << std::endl;
|
||||||
|
std::cout << "Rumble Speed: " << "left: " << opts.rumble_l << " right: " << opts.rumble_r << std::endl;
|
||||||
|
std::cout << "LED Status: " << int(opts.led) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
|
@ -685,21 +587,13 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Could/should fork here to hande multiple controllers at once
|
|
||||||
if (opts.gamepad_type == GAMEPAD_UNKNOWN)
|
if (opts.gamepad_type == GAMEPAD_UNKNOWN)
|
||||||
{
|
{
|
||||||
assert(dev_type);
|
assert(dev_type);
|
||||||
opts.gamepad_type = dev_type->type;
|
opts.gamepad_type = dev_type->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "USB Device: " << dev->bus->dirname << ":" << dev->filename << std::endl;
|
print_info(dev, dev_type, opts);
|
||||||
std::cout << "Controller: " << boost::format("\"%s\" (idVendor: 0x%04x, idProduct: 0x%04x)")
|
|
||||||
% (dev_type ? dev_type->name : "unknown") % uint16_t(dev->descriptor.idVendor) % uint16_t(dev->descriptor.idProduct) << std::endl;
|
|
||||||
std::cout << "Controller Type: " << opts.gamepad_type << std::endl;
|
|
||||||
std::cout << "Deadzone: " << opts.deadzone << std::endl;
|
|
||||||
std::cout << "Rumble Debug: " << (opts.rumble ? "on" : "off") << std::endl;
|
|
||||||
std::cout << "Rumble Speed: " << "left: " << opts.rumble_l << " right: " << opts.rumble_r << std::endl;
|
|
||||||
std::cout << "LED Status: " << int(opts.led) << std::endl;
|
|
||||||
|
|
||||||
struct usb_dev_handle* handle = usb_open(dev);
|
struct usb_dev_handle* handle = usb_open(dev);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
|
@ -759,8 +653,9 @@ int main(int argc, char** argv)
|
||||||
memset(old_data, 0, 20);
|
memset(old_data, 0, 20);
|
||||||
while(!quit)
|
while(!quit)
|
||||||
{
|
{
|
||||||
uint8_t data[20];
|
uint8_t data[32];
|
||||||
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, 20, 0 /*Timeout*/);
|
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{ // Error
|
{ // Error
|
||||||
std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
|
std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
|
||||||
|
@ -769,21 +664,9 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
// happen with the Xbox360 every now and then, just
|
// happen with the Xbox360 controller every now
|
||||||
// ignore, seems harmless
|
// and then, just ignore, seems harmless
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
else if (ret == 2 && data[1] == 0x80)
|
|
||||||
{ // wireless connect
|
|
||||||
}
|
|
||||||
else if (ret == 2 && data[1] == 0x80)
|
|
||||||
{ // wireless disconnect
|
|
||||||
}
|
|
||||||
else if (ret == 29 && data[1] == 0x01)
|
|
||||||
{
|
|
||||||
xpad_process_packet(xpad, 0, (char*) ((unsigned long)xpad->idata + 4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
|
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
|
||||||
{
|
{
|
||||||
if (memcmp(data, old_data, 20) == 0)
|
if (memcmp(data, old_data, 20) == 0)
|
||||||
|
|
130
xboxdrv.hpp
130
xboxdrv.hpp
|
@ -18,136 +18,6 @@
|
||||||
|
|
||||||
#ifndef HEADER_XBOX360_HPP
|
#ifndef HEADER_XBOX360_HPP
|
||||||
#define HEADER_XBOX360_HPP
|
#define HEADER_XBOX360_HPP
|
||||||
|
|
||||||
struct Xbox360Msg
|
|
||||||
{
|
|
||||||
// -------------------------
|
|
||||||
unsigned int type :8;
|
|
||||||
unsigned int length :8;
|
|
||||||
|
|
||||||
// data[2] ------------------
|
|
||||||
unsigned int dpad_up :1;
|
|
||||||
unsigned int dpad_down :1;
|
|
||||||
unsigned int dpad_left :1;
|
|
||||||
unsigned int dpad_right :1;
|
|
||||||
|
|
||||||
unsigned int start :1;
|
|
||||||
unsigned int back :1;
|
|
||||||
|
|
||||||
unsigned int thumb_l :1;
|
|
||||||
unsigned int thumb_r :1;
|
|
||||||
|
|
||||||
// data[3] ------------------
|
|
||||||
unsigned int lb :1;
|
|
||||||
unsigned int rb :1;
|
|
||||||
unsigned int guide :1;
|
|
||||||
unsigned int dummy1 :1;
|
|
||||||
|
|
||||||
unsigned int a :1;
|
|
||||||
unsigned int b :1;
|
|
||||||
unsigned int x :1;
|
|
||||||
unsigned int y :1;
|
|
||||||
|
|
||||||
// data[4] ------------------
|
|
||||||
unsigned int lt :8;
|
|
||||||
unsigned int rt :8;
|
|
||||||
|
|
||||||
// data[6] ------------------
|
|
||||||
int x1 :16;
|
|
||||||
int y1 :16;
|
|
||||||
|
|
||||||
// data[10] -----------------
|
|
||||||
int x2 :16;
|
|
||||||
int y2 :16;
|
|
||||||
|
|
||||||
// data[14]; ----------------
|
|
||||||
unsigned int dummy2 :32;
|
|
||||||
unsigned int dummy3 :16;
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
struct Xbox360GuitarMsg
|
|
||||||
{
|
|
||||||
// -------------------------
|
|
||||||
unsigned int type :8;
|
|
||||||
unsigned int length :8;
|
|
||||||
|
|
||||||
// data[2] ------------------
|
|
||||||
unsigned int dpad_up :1; // also strum-up
|
|
||||||
unsigned int dpad_down :1; // also strum-down
|
|
||||||
unsigned int dpad_left :1;
|
|
||||||
unsigned int dpad_right :1;
|
|
||||||
|
|
||||||
unsigned int start :1;
|
|
||||||
unsigned int back :1;
|
|
||||||
|
|
||||||
unsigned int thumb_l :1; // unused
|
|
||||||
unsigned int thumb_r :1; // unused
|
|
||||||
|
|
||||||
// data[3] ------------------
|
|
||||||
unsigned int orange :1; // 5
|
|
||||||
unsigned int rb :1; // unused
|
|
||||||
unsigned int guide :1;
|
|
||||||
unsigned int dummy1 :1; // unused
|
|
||||||
|
|
||||||
unsigned int green :1; // 1, A
|
|
||||||
unsigned int red :1; // 2, B
|
|
||||||
unsigned int blue :1; // 4, X
|
|
||||||
unsigned int yellow :1; // 3, Y
|
|
||||||
|
|
||||||
// data[4] ------------------
|
|
||||||
unsigned int lt :8; // unknown
|
|
||||||
unsigned int rt :8; // unknown
|
|
||||||
|
|
||||||
// data[6] ------------------
|
|
||||||
int x1 :16; // unused
|
|
||||||
int y1 :16; // unused
|
|
||||||
|
|
||||||
// data[10] -----------------
|
|
||||||
int whammy :16;
|
|
||||||
int tilt :16;
|
|
||||||
|
|
||||||
// data[14]; ----------------
|
|
||||||
unsigned int dummy2 :32; // unused
|
|
||||||
unsigned int dummy3 :16; // unused
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
struct XboxMsg
|
|
||||||
{
|
|
||||||
// --------------------------
|
|
||||||
unsigned int type :8;
|
|
||||||
unsigned int length :8;
|
|
||||||
|
|
||||||
// data[2] ------------------
|
|
||||||
unsigned int dpad_up :1;
|
|
||||||
unsigned int dpad_down :1;
|
|
||||||
unsigned int dpad_left :1;
|
|
||||||
unsigned int dpad_right :1;
|
|
||||||
|
|
||||||
unsigned int start :1;
|
|
||||||
unsigned int back :1;
|
|
||||||
|
|
||||||
unsigned int thumb_l :1;
|
|
||||||
unsigned int thumb_r :1;
|
|
||||||
|
|
||||||
// data[3] ------------------
|
|
||||||
unsigned int dummy :8;
|
|
||||||
unsigned int a :8;
|
|
||||||
unsigned int b :8;
|
|
||||||
unsigned int x :8;
|
|
||||||
unsigned int y :8;
|
|
||||||
unsigned int black :8;
|
|
||||||
unsigned int white :8;
|
|
||||||
unsigned int lt :8;
|
|
||||||
unsigned int rt :8;
|
|
||||||
|
|
||||||
// data[6] ------------------
|
|
||||||
int x1 :16;
|
|
||||||
int y1 :16;
|
|
||||||
|
|
||||||
// data[10] -----------------
|
|
||||||
int x2 :16;
|
|
||||||
int y2 :16;
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
enum GamepadType {
|
enum GamepadType {
|
||||||
GAMEPAD_UNKNOWN,
|
GAMEPAD_UNKNOWN,
|
||||||
|
|
142
xboxmsg.cpp
Normal file
142
xboxmsg.cpp
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/format.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Xbox360GuitarMsg& msg)
|
||||||
|
{
|
||||||
|
out << boost::format(" whammy:%6d tilt:%6d | up:%d down:%d left:%d right:%d | back:%d guide:%d start:%d | green:%d red:%d yellow:%d blue:%d orange:%d ")
|
||||||
|
% int(msg.whammy)
|
||||||
|
% int(msg.tilt)
|
||||||
|
% int(msg.dpad_up)
|
||||||
|
% int(msg.dpad_down)
|
||||||
|
% int(msg.dpad_left)
|
||||||
|
% int(msg.dpad_right)
|
||||||
|
% int(msg.back)
|
||||||
|
% int(msg.guide)
|
||||||
|
% int(msg.start)
|
||||||
|
% int(msg.green)
|
||||||
|
% int(msg.red)
|
||||||
|
% int(msg.yellow)
|
||||||
|
% int(msg.blue)
|
||||||
|
% int(msg.orange);
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
out << boost::format("| dummy: %d %d %d %d %02hhx %02hhx %04hx %04hx %02x %02x")
|
||||||
|
% int(msg.thumb_l)
|
||||||
|
% int(msg.thumb_r)
|
||||||
|
% int(msg.rb)
|
||||||
|
% int(msg.dummy1)
|
||||||
|
|
||||||
|
% int(msg.lt)
|
||||||
|
% int(msg.rt)
|
||||||
|
|
||||||
|
% int16_t(msg.x1)
|
||||||
|
% int16_t(msg.y1)
|
||||||
|
|
||||||
|
% int(msg.dummy2)
|
||||||
|
% int(msg.dummy3);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Xbox360Msg& msg)
|
||||||
|
{
|
||||||
|
out << boost::format("S1:(%6d, %6d)")
|
||||||
|
% int(msg.x1) % int(msg.y1);
|
||||||
|
|
||||||
|
out << boost::format(" S2:(%6d, %6d)")
|
||||||
|
% int(msg.x2) % int(msg.y2);
|
||||||
|
|
||||||
|
out << boost::format(" [u:%d|d:%d|l:%d|r:%d]")
|
||||||
|
% int(msg.dpad_up)
|
||||||
|
% int(msg.dpad_down)
|
||||||
|
% int(msg.dpad_left)
|
||||||
|
% int(msg.dpad_right);
|
||||||
|
|
||||||
|
out << " back:" << msg.back;
|
||||||
|
out << " guide:" << msg.guide;
|
||||||
|
out << " start:" << msg.start;
|
||||||
|
|
||||||
|
out << " sl:" << msg.thumb_l;
|
||||||
|
out << " sr:" << msg.thumb_r;
|
||||||
|
|
||||||
|
out << " A:" << msg.a;
|
||||||
|
out << " B:" << msg.b;
|
||||||
|
out << " X:" << msg.x;
|
||||||
|
out << " Y:" << msg.y;
|
||||||
|
|
||||||
|
out << " LB:" << msg.lb;
|
||||||
|
out << " RB:" << msg.rb;
|
||||||
|
|
||||||
|
out << boost::format(" LT:%3d RT:%3d")
|
||||||
|
% int(msg.lt) % int(msg.rt);
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
out << " Dummy: " << msg.dummy1 << " " << msg.dummy2 << " " << msg.dummy3;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const XboxMsg& msg)
|
||||||
|
{
|
||||||
|
out << boost::format(" S1:(%6d, %6d) S2:(%6d, %6d) "
|
||||||
|
" [u:%d|d:%d|l:%d|r:%d] "
|
||||||
|
" start:%d back:%d "
|
||||||
|
" sl:%d sr:%d "
|
||||||
|
" A:%3d B:%3d X:%3d Y:%3d "
|
||||||
|
" black:%3d white:%3d "
|
||||||
|
" LT:%3d RT:%3d ")
|
||||||
|
% int(msg.x1) % int(msg.y1)
|
||||||
|
% int(msg.x2) % int(msg.y2)
|
||||||
|
|
||||||
|
% int(msg.dpad_up)
|
||||||
|
% int(msg.dpad_down)
|
||||||
|
% int(msg.dpad_left)
|
||||||
|
% int(msg.dpad_right)
|
||||||
|
|
||||||
|
% int(msg.start)
|
||||||
|
% int(msg.back)
|
||||||
|
|
||||||
|
% int(msg.thumb_l)
|
||||||
|
% int(msg.thumb_r)
|
||||||
|
|
||||||
|
% int(msg.a)
|
||||||
|
% int(msg.b)
|
||||||
|
% int(msg.x)
|
||||||
|
% int(msg.y)
|
||||||
|
|
||||||
|
% int(msg.black)
|
||||||
|
% int(msg.white)
|
||||||
|
|
||||||
|
% int(msg.lt)
|
||||||
|
% int(msg.rt);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
167
xboxmsg.hpp
Normal file
167
xboxmsg.hpp
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* $Id$
|
||||||
|
** __ __ __ ___ __ __ __ __
|
||||||
|
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||||
|
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||||
|
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||||
|
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||||
|
** \/ \/ \/ \/ \/
|
||||||
|
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||||
|
**
|
||||||
|
** This program is free software; you can redistribute it and/or
|
||||||
|
** modify it under the terms of the GNU General Public License
|
||||||
|
** as published by the Free Software Foundation; either version 2
|
||||||
|
** of the License, or (at your option) any later version.
|
||||||
|
**
|
||||||
|
** This program is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with this program; if not, write to the Free Software
|
||||||
|
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
** 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_XBOXMSG_HPP
|
||||||
|
#define HEADER_XBOXMSG_HPP
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
struct Xbox360Msg
|
||||||
|
{
|
||||||
|
// -------------------------
|
||||||
|
unsigned int type :8;
|
||||||
|
unsigned int length :8;
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1;
|
||||||
|
unsigned int dpad_down :1;
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1;
|
||||||
|
unsigned int thumb_r :1;
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int lb :1;
|
||||||
|
unsigned int rb :1;
|
||||||
|
unsigned int guide :1;
|
||||||
|
unsigned int dummy1 :1;
|
||||||
|
|
||||||
|
unsigned int a :1;
|
||||||
|
unsigned int b :1;
|
||||||
|
unsigned int x :1;
|
||||||
|
unsigned int y :1;
|
||||||
|
|
||||||
|
// data[4] ------------------
|
||||||
|
unsigned int lt :8;
|
||||||
|
unsigned int rt :8;
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16;
|
||||||
|
int y1 :16;
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int x2 :16;
|
||||||
|
int y2 :16;
|
||||||
|
|
||||||
|
// data[14]; ----------------
|
||||||
|
unsigned int dummy2 :32;
|
||||||
|
unsigned int dummy3 :16;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
struct Xbox360GuitarMsg
|
||||||
|
{
|
||||||
|
// -------------------------
|
||||||
|
unsigned int type :8;
|
||||||
|
unsigned int length :8;
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1; // also strum-up
|
||||||
|
unsigned int dpad_down :1; // also strum-down
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1; // unused
|
||||||
|
unsigned int thumb_r :1; // unused
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int orange :1; // 5
|
||||||
|
unsigned int rb :1; // unused
|
||||||
|
unsigned int guide :1;
|
||||||
|
unsigned int dummy1 :1; // unused
|
||||||
|
|
||||||
|
unsigned int green :1; // 1, A
|
||||||
|
unsigned int red :1; // 2, B
|
||||||
|
unsigned int blue :1; // 4, X
|
||||||
|
unsigned int yellow :1; // 3, Y
|
||||||
|
|
||||||
|
// data[4] ------------------
|
||||||
|
unsigned int lt :8; // unknown
|
||||||
|
unsigned int rt :8; // unknown
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16; // unused
|
||||||
|
int y1 :16; // unused
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int whammy :16;
|
||||||
|
int tilt :16;
|
||||||
|
|
||||||
|
// data[14]; ----------------
|
||||||
|
unsigned int dummy2 :32; // unused
|
||||||
|
unsigned int dummy3 :16; // unused
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
struct XboxMsg
|
||||||
|
{
|
||||||
|
// --------------------------
|
||||||
|
unsigned int type :8;
|
||||||
|
unsigned int length :8;
|
||||||
|
|
||||||
|
// data[2] ------------------
|
||||||
|
unsigned int dpad_up :1;
|
||||||
|
unsigned int dpad_down :1;
|
||||||
|
unsigned int dpad_left :1;
|
||||||
|
unsigned int dpad_right :1;
|
||||||
|
|
||||||
|
unsigned int start :1;
|
||||||
|
unsigned int back :1;
|
||||||
|
|
||||||
|
unsigned int thumb_l :1;
|
||||||
|
unsigned int thumb_r :1;
|
||||||
|
|
||||||
|
// data[3] ------------------
|
||||||
|
unsigned int dummy :8;
|
||||||
|
unsigned int a :8;
|
||||||
|
unsigned int b :8;
|
||||||
|
unsigned int x :8;
|
||||||
|
unsigned int y :8;
|
||||||
|
unsigned int black :8;
|
||||||
|
unsigned int white :8;
|
||||||
|
unsigned int lt :8;
|
||||||
|
unsigned int rt :8;
|
||||||
|
|
||||||
|
// data[6] ------------------
|
||||||
|
int x1 :16;
|
||||||
|
int y1 :16;
|
||||||
|
|
||||||
|
// data[10] -----------------
|
||||||
|
int x2 :16;
|
||||||
|
int y2 :16;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Xbox360GuitarMsg& msg);
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Xbox360Msg& msg);
|
||||||
|
std::ostream& operator<<(std::ostream& out, const XboxMsg& msg);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
Loading…
Reference in a new issue