diff --git a/SConstruct b/SConstruct
index eeac5fb..98e1c41 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,14 +1,18 @@
# -*- python -*-
env = Environment(CPPFLAGS=["-g", "-O0", "-Wall"], LIBS=["usb"])
-env.Program("xboxdrv", ["xboxdrv.cpp", "xboxmsg.cpp", "uinput.cpp"])
+env.Program("xboxdrv", ["xboxdrv.cpp",
+ "xboxmsg.cpp",
+ "uinput.cpp",
+ "xbox_controller.cpp",
+ "xbox360_controller.cpp",
+ "xbox360_wireless_controller.cpp",
+ ])
env.Program("inputdrv",
["inputdrv.cpp",
"xbox360_driver.cpp",
"evdev_driver.cpp",
"xbox360_usb_thread.cpp",
- "xbox360_controller.cpp",
- "xbox360_wireless_controller.cpp",
"control.cpp",
"abs_to_rel.cpp",
"abs_to_btn.cpp",
diff --git a/TODO b/TODO
index ef9863f..4231614 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,11 @@
+Test:
+=====
+ --wid
+ controller type enforcment is broken
+ deadzone is broken
+ Rumble
+ LED
+
Easy interface:
===============
--trigger-as-zaxis
diff --git a/uinput.cpp b/uinput.cpp
index 31a0597..19a9573 100644
--- a/uinput.cpp
+++ b/uinput.cpp
@@ -16,6 +16,7 @@
** along with this program. If not, see .
*/
+#include
#include
#include
#include
@@ -261,6 +262,23 @@ uInput::send_axis(uint16_t code, int32_t value)
write(fd, &ev, sizeof(ev));
}
+void
+uInput::send(XboxGenericMsg& msg)
+{
+ if (msg.type == GAMEPAD_XBOX)
+ send(msg.xbox);
+ else if (msg.type == GAMEPAD_XBOX_MAT)
+ send(msg.xbox);
+ else if (msg.type == GAMEPAD_XBOX360)
+ send(msg.xbox360);
+ else if (msg.type == GAMEPAD_XBOX360_WIRELESS)
+ send(msg.xbox360);
+ else if (msg.type == GAMEPAD_XBOX360_GUITAR)
+ send(msg.guitar);
+ else
+ assert(!"Unknown XboxGenericMsg type");
+}
+
void
uInput::send(Xbox360Msg& msg)
{
diff --git a/uinput.hpp b/uinput.hpp
index a3c3477..a94b007 100644
--- a/uinput.hpp
+++ b/uinput.hpp
@@ -51,7 +51,8 @@ public:
void setup_xbox360_gamepad(GamepadType type);
void setup_xbox360_guitar();
-
+
+ void send(XboxGenericMsg& msg);
void send(Xbox360Msg& msg);
void send(Xbox360GuitarMsg& msg);
void send(XboxMsg& msg);
diff --git a/xbox360_controller.cpp b/xbox360_controller.cpp
index 0c0a568..f6fa5bf 100644
--- a/xbox360_controller.cpp
+++ b/xbox360_controller.cpp
@@ -18,13 +18,15 @@
#include
#include
+#include
+#include
#include "xboxmsg.hpp"
#include "xbox360_controller.hpp"
Xbox360Controller::Xbox360Controller(struct usb_device* dev,
XPadDevice* dev_type)
{
- struct usb_dev_handle* handle = usb_open(dev);
+ handle = usb_open(dev);
if (!handle)
{
throw std::runtime_error("Error opening Xbox360 controller");
@@ -38,11 +40,17 @@ Xbox360Controller::Xbox360Controller(struct usb_device* dev,
}
}
+Xbox360Controller::~Xbox360Controller()
+{
+ usb_release_interface(handle, 0);
+ usb_close(handle);
+}
+
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);
+ usb_interrupt_write(handle, 2, rumblecmd, sizeof(rumblecmd), 0);
}
void
@@ -53,7 +61,7 @@ Xbox360Controller::set_led(uint8_t status)
}
void
-Xbox360Controller::read(Xbox360Msg& msg)
+Xbox360Controller::read(XboxGenericMsg& msg)
{
uint8_t data[32];
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/);
@@ -71,7 +79,18 @@ Xbox360Controller::read(Xbox360Msg& msg)
}
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
{
- msg = (Xbox360Msg&)data;
+ msg.type = GAMEPAD_XBOX360;
+ msg.xbox360 = *reinterpret_cast(data);
+ }
+ else
+ {
+ std::cout << "Unknown data: bytes: " << ret
+ << " Data: ";
+
+ for(int j = 0; j < ret; ++j)
+ std::cout << boost::format("0x%02x ") % int(data[j]);
+
+ std::cout << std::endl;
}
}
diff --git a/xbox360_controller.hpp b/xbox360_controller.hpp
index 9ca8f94..8962198 100644
--- a/xbox360_controller.hpp
+++ b/xbox360_controller.hpp
@@ -20,11 +20,12 @@
#define HEADER_XBOX360_CONTROLLER_HPP
#include
+#include "xbox_generic_controller.hpp"
struct XPadDevice;
/** */
-class Xbox360Controller
+class Xbox360Controller : public XboxGenericController
{
private:
struct usb_device* dev;
@@ -34,10 +35,11 @@ private:
public:
Xbox360Controller(struct usb_device* dev,
XPadDevice* dev_type);
+ ~Xbox360Controller();
void set_rumble(uint8_t left, uint8_t right);
void set_led(uint8_t status);
- void read(Xbox360Msg& msg);
+ void read(XboxGenericMsg& msg);
private:
Xbox360Controller (const Xbox360Controller&);
diff --git a/xbox360_wireless_controller.cpp b/xbox360_wireless_controller.cpp
index 3e1993d..6b0abfd 100644
--- a/xbox360_wireless_controller.cpp
+++ b/xbox360_wireless_controller.cpp
@@ -34,7 +34,7 @@ Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev,
endpoint = controller_id*2 + 1;
interface = controller_id*2;
- struct usb_dev_handle* handle = usb_open(dev);
+ handle = usb_open(dev);
if (!handle)
{
throw std::runtime_error("Xbox360WirelessController: Error opening Xbox360 controller");
@@ -48,6 +48,12 @@ Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev,
}
}
+Xbox360WirelessController::~Xbox360WirelessController()
+{
+ usb_release_interface(handle, interface);
+ usb_close(handle);
+}
+
void
Xbox360WirelessController::set_rumble(uint8_t left, uint8_t right)
{
@@ -67,7 +73,7 @@ Xbox360WirelessController::set_led(uint8_t status)
}
void
-Xbox360WirelessController::read(Xbox360Msg& msg)
+Xbox360WirelessController::read(XboxGenericMsg& msg)
{
uint8_t data[32];
int ret = usb_interrupt_read(handle, endpoint, (char*)data, sizeof(data), 0 /*Timeout*/);
@@ -112,7 +118,8 @@ Xbox360WirelessController::read(Xbox360Msg& msg)
}
else if (data[0] == 0x00 && data[1] == 0x01 && data[2] == 0x00 && data[3] == 0xf0 && data[4] == 0x00 && data[5] == 0x13)
{
- msg = *reinterpret_cast(&data[6]);
+ msg.type = GAMEPAD_XBOX360_WIRELESS;
+ msg.xbox360 = *reinterpret_cast(&data[6]);
}
else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13)
{ // Battery status
diff --git a/xbox360_wireless_controller.hpp b/xbox360_wireless_controller.hpp
index 7ea7147..5ca4666 100644
--- a/xbox360_wireless_controller.hpp
+++ b/xbox360_wireless_controller.hpp
@@ -19,10 +19,12 @@
#ifndef HEADER_XBOX360_WIRELESS_CONTROLLER_HPP
#define HEADER_XBOX360_WIRELESS_CONTROLLER_HPP
+#include "xbox_generic_controller.hpp"
+
struct XPadDevice;
/** */
-class Xbox360WirelessController
+class Xbox360WirelessController : public XboxGenericController
{
private:
struct usb_device* dev;
@@ -37,10 +39,11 @@ public:
Xbox360WirelessController(struct usb_device* dev,
XPadDevice* dev_type,
int controller_id);
+ virtual ~Xbox360WirelessController();
void set_rumble(uint8_t left, uint8_t right);
void set_led(uint8_t status);
- void read(Xbox360Msg& msg);
+ void read(XboxGenericMsg& msg);
uint8_t get_battery_status() const;
private:
Xbox360WirelessController (const Xbox360WirelessController&);
diff --git a/xbox_controller.cpp b/xbox_controller.cpp
index de7320c..d55674e 100644
--- a/xbox_controller.cpp
+++ b/xbox_controller.cpp
@@ -19,12 +19,12 @@
#include
#include
#include "xboxmsg.hpp"
-#include "xbox360_controller.hpp"
+#include "xbox_controller.hpp"
XboxController::XboxController(struct usb_device* dev,
- XPadDevice* dev_type)
+ XPadDevice* dev_type)
{
- struct usb_dev_handle* handle = usb_open(dev);
+ handle = usb_open(dev);
if (!handle)
{
throw std::runtime_error("Error opening Xbox360 controller");
@@ -38,10 +38,16 @@ XboxController::XboxController(struct usb_device* dev,
}
}
+XboxController::~XboxController()
+{
+ usb_release_interface(handle, 0);
+ usb_close(handle);
+}
+
void
XboxController::set_rumble(uint8_t left, uint8_t right)
{
- char rumblecmd[] = { 0x00, 0x06, 0x00, r, 0x00, l };
+ char rumblecmd[] = { 0x00, 0x06, 0x00, left, 0x00, right };
usb_interrupt_write(handle, 2, rumblecmd, sizeof(rumblecmd), 0);
}
@@ -52,8 +58,9 @@ XboxController::set_led(uint8_t status)
}
void
-XboxController::read(XboxGenericMsg& msg);
+XboxController::read(XboxGenericMsg& msg)
{
+ // FIXME: Add tracking for duplicate data packages (send by logitech controller)
uint8_t data[32];
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/);
diff --git a/xbox_controller.hpp b/xbox_controller.hpp
index c08ef72..f68da1d 100644
--- a/xbox_controller.hpp
+++ b/xbox_controller.hpp
@@ -20,11 +20,12 @@
#define HEADER_XBOX_CONTROLLER_HPP
#include
+#include "xbox_generic_controller.hpp"
struct XPadDevice;
/** */
-class XboxController
+class XboxController : public XboxGenericController
{
private:
struct usb_device* dev;
@@ -33,7 +34,8 @@ private:
public:
XboxController(struct usb_device* dev,
- XPadDevice* dev_type);
+ XPadDevice* dev_type);
+ virtual ~XboxController();
void set_rumble(uint8_t left, uint8_t right);
void set_led(uint8_t status);
diff --git a/xbox_generic_controller.hpp b/xbox_generic_controller.hpp
new file mode 100644
index 0000000..6b95e27
--- /dev/null
+++ b/xbox_generic_controller.hpp
@@ -0,0 +1,41 @@
+/*
+** Xbox/Xbox360 USB Gamepad Userspace Driver
+** Copyright (C) 2008 Ingo Ruhnke
+**
+** 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 3 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, see .
+*/
+
+#ifndef HEADER_XBOX_GENERIC_CONTROLLER_HPP
+#define HEADER_XBOX_GENERIC_CONTROLLER_HPP
+
+/** */
+class XboxGenericController
+{
+private:
+public:
+ XboxGenericController() {}
+ virtual ~XboxGenericController() {}
+
+ virtual void set_rumble(uint8_t left, uint8_t right) =0;
+ virtual void set_led(uint8_t status) =0;
+ virtual void read(XboxGenericMsg& msg) =0;
+
+private:
+ XboxGenericController (const XboxGenericController&);
+ XboxGenericController& operator= (const XboxGenericController&);
+};
+
+#endif
+
+/* EOF */
diff --git a/xboxdrv.cpp b/xboxdrv.cpp
index 05d1298..8a165bf 100644
--- a/xboxdrv.cpp
+++ b/xboxdrv.cpp
@@ -23,6 +23,11 @@
#include
#include "uinput.hpp"
#include "xboxmsg.hpp"
+#include "xbox_controller.hpp"
+#include "xbox360_controller.hpp"
+#include "xbox360_wireless_controller.hpp"
+#include "xbox_generic_controller.hpp"
+
#include "xboxdrv.hpp"
@@ -106,8 +111,8 @@ void list_controller()
struct usb_bus* busses = usb_get_busses();
int id = 0;
- std::cout << " id | idVendor | idProduct | Name" << std::endl;
- std::cout << "----+----------+-----------+---------------------------------" << std::endl;
+ std::cout << " id | wid | idVendor | idProduct | Name" << std::endl;
+ std::cout << "----+-----+----------+-----------+--------------------------------------" << std::endl;
for (struct usb_bus* bus = busses; bus; bus = bus->next)
{
for (struct usb_device* dev = bus->devices; dev; dev = dev->next)
@@ -117,12 +122,30 @@ void list_controller()
if (dev->descriptor.idVendor == xpad_devices[i].idVendor &&
dev->descriptor.idProduct == xpad_devices[i].idProduct)
{
- std::cout << boost::format(" %2d | 0x%04x | 0x%04x | %s")
- % id
- % int(xpad_devices[i].idVendor)
- % int(xpad_devices[i].idProduct)
- % xpad_devices[i].name
- << std::endl;
+ if (xpad_devices[i].type == GAMEPAD_XBOX360_WIRELESS)
+ {
+ for(int wid = 0; wid < 3; ++wid)
+ {
+ std::cout << boost::format(" %2d | %2d | 0x%04x | 0x%04x | %s (Port: %s)")
+ % id
+ % wid
+ % int(xpad_devices[i].idVendor)
+ % int(xpad_devices[i].idProduct)
+ % xpad_devices[i].name
+ % wid
+ << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << boost::format(" %2d | %2d | 0x%04x | 0x%04x | %s")
+ % id
+ % 0
+ % int(xpad_devices[i].idVendor)
+ % int(xpad_devices[i].idProduct)
+ % xpad_devices[i].name
+ << std::endl;
+ }
id += 1;
break;
}
@@ -202,6 +225,7 @@ struct CommandLineOptions
int rumble_l;
int rumble_r;
int controller_id;
+ int wireless_id;
bool instant_exit;
bool no_uinput;
GamepadType gamepad_type;
@@ -217,6 +241,7 @@ struct CommandLineOptions
rumble_l = 0;
rumble_r = 0;
controller_id = 0;
+ wireless_id = 0;
instant_exit = false;
no_uinput = false;
gamepad_type = GAMEPAD_UNKNOWN;
@@ -236,7 +261,8 @@ void print_command_line_help(int argc, char** argv)
std::cout << " --help-led list possible values for the led" << std::endl;
std::cout << " --help-devices list supported devices" << std::endl;
std::cout << " -v, --verbose display controller events" << std::endl;
- std::cout << " -i, --id N use controller number (default: 0)" << std::endl;
+ std::cout << " -i, --id N use controller with id N (default: 0)" << std::endl;
+ std::cout << " -w, --wid N use wireless controller with wid N (default: 0)" << std::endl;
std::cout << " -L, --list-controller list available controllers" << std::endl;
std::cout << " -R, --test-rumble map rumbling to LT and RT (for testing only)" << std::endl;
std::cout << " --no-uinput do not try to start uinput event dispatching" << std::endl;
@@ -262,25 +288,25 @@ void print_command_line_help(int argc, char** argv)
void print_led_help()
{
- std::cout <<
- "Possible values for '--led VALUE' are:\n\n"
- " 0: off\n"
- " 1: all blinking\n"
- " 2: 1/top-left blink, then on\n"
- " 3: 2/top-right blink, then on\n"
- " 4: 3/bottom-left blink, then on\n"
- " 5: 4/bottom-right blink, then on\n"
- " 6: 1/top-left on\n"
- " 7: 2/top-right on\n"
- " 8: 3/bottom-left on\n"
- " 9: 4/bottom-right on\n"
- " 10: rotate\n"
- " 11: blink\n"
- " 12: blink slower\n"
- " 13: rotate with two lights\n"
- " 14: blink\n"
- " 15: blink once\n"
- << std::endl;
+ std::cout <<
+ "Possible values for '--led VALUE' are:\n\n"
+ " 0: off\n"
+ " 1: all blinking\n"
+ " 2: 1/top-left blink, then on\n"
+ " 3: 2/top-right blink, then on\n"
+ " 4: 3/bottom-left blink, then on\n"
+ " 5: 4/bottom-right blink, then on\n"
+ " 6: 1/top-left on\n"
+ " 7: 2/top-right on\n"
+ " 8: 3/bottom-left on\n"
+ " 9: 4/bottom-right on\n"
+ " 10: rotate\n"
+ " 11: blink\n"
+ " 12: blink slower\n"
+ " 13: rotate with two lights\n"
+ " 14: blink\n"
+ " 15: blink once\n"
+ << std::endl;
}
void parse_command_line(int argc, char** argv, CommandLineOptions& opts)
@@ -394,6 +420,20 @@ void parse_command_line(int argc, char** argv, CommandLineOptions& opts)
exit(EXIT_FAILURE);
}
}
+ else if (strcmp(argv[i], "-w") == 0 ||
+ strcmp(argv[i], "--wid") == 0)
+ {
+ ++i;
+ if (i < argc)
+ {
+ opts.wireless_id = atoi(argv[i]);
+ }
+ else
+ {
+ std::cout << "Error: " << argv[i-1] << " expected a argument" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
else if (strcmp(argv[i], "-l") == 0 ||
strcmp(argv[i], "--led") == 0)
{
@@ -533,6 +573,8 @@ void print_info(struct usb_device* dev,
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;
+ if (dev_type->type == GAMEPAD_XBOX360_WIRELESS)
+ std::cout << "Wireless Port: " << opts.wireless_id << 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;
@@ -540,6 +582,45 @@ void print_info(struct usb_device* dev,
std::cout << "LED Status: " << int(opts.led) << std::endl;
}
+void controller_loop(XboxGenericController* controller, CommandLineOptions& opts)
+{
+ uInput* uinput = 0;
+ if (!opts.no_uinput)
+ {
+ std::cout << "Starting uinput" << std::endl;
+ uinput = new uInput(opts.gamepad_type, opts.uinput_config);
+ }
+ else
+ {
+ std::cout << "Starting without uinput" << std::endl;
+ }
+ std::cout << "\nYour Xbox360 controller should now be available as /dev/input/jsX and /dev/input/eventX" << std::endl;
+ std::cout << "Press Ctrl-c to quit" << std::endl;
+
+ bool quit = false;
+ while(!quit)
+ {
+ XboxGenericMsg msg;
+ controller->read(msg);
+ if (opts.verbose)
+ std::cout << msg << std::endl;
+ if (uinput) uinput->send(msg);
+
+ if (opts.rumble)
+ {
+ if (opts.gamepad_type == GAMEPAD_XBOX)
+ {
+ controller->set_rumble(msg.xbox.lt, msg.xbox.rt);
+ }
+ else if (opts.gamepad_type == GAMEPAD_XBOX360 ||
+ opts.gamepad_type == GAMEPAD_XBOX360_WIRELESS)
+ {
+ controller->set_rumble(msg.xbox360.lt, msg.xbox360.rt);
+ }
+ }
+ }
+}
+
int main(int argc, char** argv)
{
srand(time(0));
@@ -595,167 +676,41 @@ int main(int argc, char** argv)
print_info(dev, dev_type, opts);
- struct usb_dev_handle* handle = usb_open(dev);
- if (!handle)
+ XboxGenericController* controller = 0;
+
+ switch (dev_type->type)
{
- std::cout << "Error opening Xbox360 controller" << std::endl;
+ case GAMEPAD_XBOX:
+ case GAMEPAD_XBOX_MAT:
+ controller = new XboxController(dev, dev_type);
+ break;
+
+ case GAMEPAD_XBOX360_GUITAR:
+ case GAMEPAD_XBOX360:
+ controller = new Xbox360Controller(dev, dev_type);
+ break;
+
+ case GAMEPAD_XBOX360_WIRELESS:
+ controller = new Xbox360WirelessController(dev, dev_type, opts.wireless_id);
+ break;
+
+ default:
+ assert(!"Unknown gamepad type");
+ }
+
+ controller->set_led(opts.led);
+ controller->set_rumble(opts.rumble_l, opts.rumble_r);
+
+ if (opts.instant_exit)
+ {
+ usleep(1000);
}
else
- {
- if (usb_claim_interface(handle, 0) != 0) // FIXME: bInterfaceNumber shouldn't be hardcoded
- std::cout << "Error claiming the interface: " << usb_strerror() << std::endl;
-
- // Handle LED on Xbox360 Controller
- if (opts.gamepad_type == GAMEPAD_XBOX360 ||
- opts.gamepad_type == GAMEPAD_XBOX360_GUITAR)
- {
- char ledcmd[] = { 1, 3, opts.led };
- usb_interrupt_write(handle, 2, ledcmd, 3, 0);
- }
-
- // Switch of Rumble
- if (opts.gamepad_type == GAMEPAD_XBOX360)
- {
- char l = opts.rumble_r; // light weight
- char b = opts.rumble_l; // big weight
- char rumblecmd[] = { 0x00, 0x08, 0x00, b, l, 0x00, 0x00, 0x00 };
- usb_interrupt_write(handle, 2, rumblecmd, 8, 0);
- }
- else if (opts.gamepad_type == GAMEPAD_XBOX)
- {
- char l = opts.rumble_l;
- char b = opts.rumble_r;
- char rumblecmd[] = { 0x00, 0x06, 0x00, l, 0x00, b };
- usb_interrupt_write(handle, 2, rumblecmd, 6, 0);
- }
-
- if (opts.instant_exit)
- {
-
- }
- else
- {
- uInput* uinput = 0;
- if (!opts.no_uinput)
- {
- std::cout << "Starting uinput" << std::endl;
- uinput = new uInput(opts.gamepad_type, opts.uinput_config);
- }
- else
- {
- std::cout << "Starting without uinput" << std::endl;
- }
- std::cout << "\nYour Xbox360 controller should now be available as /dev/input/jsX and /dev/input/eventX" << std::endl;
- std::cout << "Press Ctrl-c to quit" << std::endl;
-
- bool quit = false;
- uint8_t old_data[20];
- memset(old_data, 0, 20);
- while(!quit)
- {
- uint8_t data[32];
- int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/);
-
- if (ret < 0)
- { // Error
- std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
- std::cout << "Shutting down" << std::endl;
- quit = true;
- }
- else if (ret == 0)
- {
- // happen with the Xbox360 controller every now
- // and then, just ignore, seems harmless
- }
- else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
- {
- if (memcmp(data, old_data, 20) == 0)
- {
- // Ignore the data, since nothing has changed
- }
- else
- {
- memcpy(old_data, data, 20);
-
- if (opts.gamepad_type == GAMEPAD_XBOX360_GUITAR)
- {
- Xbox360GuitarMsg& msg = (Xbox360GuitarMsg&)data;
- if (opts.verbose)
- std::cout << msg << std::endl;
-
- uinput->send(msg);
- }
- else if (opts.gamepad_type == GAMEPAD_XBOX360)
- {
- Xbox360Msg& msg = (Xbox360Msg&)data;
-
- if (abs(msg.x1) < opts.deadzone)
- msg.x1 = 0;
-
- if (abs(msg.y1) < opts.deadzone)
- msg.y1 = 0;
-
- if (abs(msg.x2) < opts.deadzone)
- msg.x2 = 0;
-
- if (abs(msg.y2) < opts.deadzone)
- msg.y2 = 0;
-
- if (opts.verbose)
- std::cout << msg << std::endl;
-
- if (uinput) uinput->send(msg);
-
- if (opts.rumble)
- {
- char l = msg.rt;
- char b = msg.lt;
- char rumblecmd[] = { 0x00, 0x08, 0x00, b, l, 0x00, 0x00, 0x00 };
- usb_interrupt_write(handle, 2, rumblecmd, 8, 0);
- }
- }
- else if (opts.gamepad_type == GAMEPAD_XBOX)
- {
- XboxMsg& msg = (XboxMsg&)data;
-
- if (opts.verbose)
- std::cout << msg << std::endl;
-
- if (uinput) uinput->send(msg);
-
- if (opts.rumble)
- {
- char l = msg.lt;
- char b = msg.rt;
- char rumblecmd[] = { 0x00, 0x06, 0x00, l, 0x00, b };
- usb_interrupt_write(handle, 2, rumblecmd, 6, 0);
- }
- }
- }
- }
- else
- {
- std::cout << "Unknown data: bytes: " << ret
- << " Data: ";
-
- for(int j = 0; j < ret; ++j)
- {
- std::cout << boost::format("0x%02x ") % int(data[j]);
- }
- //std::cout << "\r" << std::flush;
- std::cout << std::endl;
- }
- }
- }
- usb_release_interface(handle, 0); // FIXME: bInterfaceNumber shouldn't be hardcoded
-
- // Almost never reached since the user will Ctrl-c and we
- // can't use sigint since we block in usb_interrupt_read()
- usb_close(handle);
+ {
+ controller_loop(controller, opts);
+ delete controller;
}
}
-
- return 0;
}
/* EOF */
diff --git a/xboxdrv.hpp b/xboxdrv.hpp
index 99476a3..90d3684 100644
--- a/xboxdrv.hpp
+++ b/xboxdrv.hpp
@@ -18,15 +18,8 @@
#ifndef HEADER_XBOX360_HPP
#define HEADER_XBOX360_HPP
-
-enum GamepadType {
- GAMEPAD_UNKNOWN,
- GAMEPAD_XBOX,
- GAMEPAD_XBOX_MAT,
- GAMEPAD_XBOX360,
- GAMEPAD_XBOX360_WIRELESS,
- GAMEPAD_XBOX360_GUITAR
-};
+
+#include "xboxmsg.hpp"
struct XPadDevice {
GamepadType type;
diff --git a/xboxmsg.cpp b/xboxmsg.cpp
index e0f8e1b..b0ffe74 100644
--- a/xboxmsg.cpp
+++ b/xboxmsg.cpp
@@ -20,6 +20,22 @@
#include
#include "xboxmsg.hpp"
+std::ostream& operator<<(std::ostream& out, const XboxGenericMsg& msg)
+{
+ if (msg.type == GAMEPAD_XBOX)
+ return out << msg.xbox;
+ else if (msg.type == GAMEPAD_XBOX_MAT)
+ return out << msg.xbox;
+ else if (msg.type == GAMEPAD_XBOX360)
+ return out << msg.xbox360;
+ else if (msg.type == GAMEPAD_XBOX360_WIRELESS)
+ return out << msg.xbox360;
+ else if (msg.type == GAMEPAD_XBOX360_GUITAR)
+ return out << msg.guitar;
+ else
+ return out << "Error: Unhandled XboxGenericMsg type: " << msg.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 ")
diff --git a/xboxmsg.hpp b/xboxmsg.hpp
index e45e15d..2ae66bf 100644
--- a/xboxmsg.hpp
+++ b/xboxmsg.hpp
@@ -21,6 +21,15 @@
#include
+enum GamepadType {
+ GAMEPAD_UNKNOWN,
+ GAMEPAD_XBOX,
+ GAMEPAD_XBOX_MAT,
+ GAMEPAD_XBOX360,
+ GAMEPAD_XBOX360_WIRELESS,
+ GAMEPAD_XBOX360_GUITAR
+};
+
struct Xbox360Msg
{
// -------------------------
@@ -150,10 +159,22 @@ struct XboxMsg
int x2 :16;
int y2 :16;
} __attribute__((__packed__));
+
+
+struct XboxGenericMsg
+{
+ GamepadType type;
+ union {
+ struct Xbox360GuitarMsg guitar;
+ struct Xbox360Msg xbox360;
+ struct XboxMsg xbox;
+ };
+};
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);
+std::ostream& operator<<(std::ostream& out, const XboxGenericMsg& msg);
#endif