- added --device BUS:DEV option

This commit is contained in:
Ingo Ruhnke 2008-04-20 06:58:20 +02:00
parent 841f95a2f1
commit c89ac7e19c
4 changed files with 169 additions and 32 deletions

View file

@ -3,6 +3,11 @@ XBox Gamepad Userspace Driver:
* Ingo Ruhnke <grumbel@gmx>
XBox Gamepad Userspace Driver Testing:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Julien <julroy67@gmail.com> (XBox360 Guitar)
Parts of the code are based on XBox Kernel driver (xpad.c/xpad.h) by:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Marko Friedemann <mfr@bmx-chemnitz.de>

29
TODO
View file

@ -1,3 +1,32 @@
// wire: { 0x00, 0x08, 0x00, large, small, 0x00, 0x00, 0x00 };
// wireless: { 0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00};
^^^^ typo?
void Wireless360Controller::SetRumbleMotors(unsigned char large, unsigned char small)
{
char buf[] = {0x00, 0x01, 0x0f, 0xc0, 0x00, large, small, 0x00, 0x00, 0x00, 0x00, 0x00};
WirelessDevice *device;
device = OSDynamicCast(WirelessDevice, getProvider());
if (device != NULL)
device->SendPacket(buf, sizeof(buf));
}
-----
Tilt Sensor: is mapped to the second axis of S2, to LT and RT (three parts)
- Range for 2nd axis of S2 : -32768 when guitar is straight down and 32767 when she is straight up.
- Range for LT : ~200 not very precise and ~60 at min.
- Range for RT : ~190 not very precise and ~55 at min.
dummy should stay mostly 0, except the position five and six, which
are the LT/RT trigger. We can either just ignore them or you can try
to find out if they have any meaning.
They control guitar rotation, hmm hard to explain, it's when I rotate the guitar in front of me, it detects if the guitar is in the correct position.
-----
* add -type option to enforce controller type
* Question: Firestorm Dual Power: How to get rumble to work when there is no endpoint to send data to?

View file

@ -96,7 +96,7 @@ cat_usb_device(struct usb_device* dev, int ep)
while(!quit)
{
uint8_t data[32];
int ret = usb_bulk_read(handle, ep, (char*)data, sizeof(data), 0);
int ret = usb_interrupt_read(handle, ep, (char*)data, sizeof(data), 0);
if (ret < 0)
{
std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
@ -126,7 +126,7 @@ cat_usb_device(struct usb_device* dev, int ep)
}
std::cout << "Writing random data" << std::endl;
if (usb_bulk_write(handle, 0, rumblecmd, len, 0) < 0)
if (usb_interrupt_write(handle, 0, rumblecmd, len, 0) < 0)
{
std::cout << "Write Error: " << usb_strerror() << std::endl;
}

View file

@ -246,6 +246,28 @@ void list_controller()
std::cout << "\nNo controller detected" << std::endl;
}
bool find_controller_by_path(char* busid, char* devid,struct usb_device** xbox_device)
{
struct usb_bus* busses = usb_get_busses();
for (struct usb_bus* bus = busses; bus; bus = bus->next)
{
if (strcmp(bus->dirname, busid) == 0)
{
for (struct usb_device* dev = bus->devices; dev; dev = dev->next)
{
if (strcmp(dev->filename, devid) == 0)
{
*xbox_device = dev;
return true;
}
}
}
}
return 0;
}
bool find_xbox360_controller(int id, struct usb_device** xbox_device, XPadDevice** type)
{
struct usb_bus* busses = usb_get_busses();
@ -293,9 +315,11 @@ int main(int argc, char** argv)
int rumble_r = 0;
int controller_id = 0;
bool instant_exit = false;
uInputCfg uinput_config;
bool no_uinput = false;
int forced_type = -1;
int gamepad_type = -1;
char busid[4] = "\0";
char devid[4] = "\0";
uInputCfg uinput_config;
for(int i = 1; i < argc; ++i)
{
@ -311,10 +335,13 @@ int main(int argc, char** argv)
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 << " -L, --list-controller list available controllers" << std::endl;
std::cout << " --test-rumble map rumbling to LT and RT (for testing only)" << 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;
std::cout << std::endl;
std::cout << "Device Options: " << std::endl;
std::cout << " -d, --device BUS:DEV Use device BUS:DEV, do not do any scanning" << std::endl;
std::cout << std::endl;
std::cout << "Status Options: " << std::endl;
std::cout << " -l, --led NUM set LED status, see --list-led-values (default: 0)" << std::endl;
std::cout << " -r, --rumble L,R set the speed for both rumble motors [0-255] (default: 0,0)" << std::endl;
@ -335,7 +362,8 @@ int main(int argc, char** argv)
{
verbose = true;
}
else if (strcmp(argv[i], "--test-rumble") == 0)
else if (strcmp(argv[i], "--test-rumble") == 0 ||
strcmp(argv[i], "-R") == 0)
{
rumble = true;
}
@ -345,9 +373,16 @@ int main(int argc, char** argv)
++i;
if (i < argc)
{
sscanf(argv[i], "%d,%d", &rumble_l, &rumble_r);
rumble_l = std::max(0, std::min(255, rumble_l));
rumble_r = std::max(0, std::min(255, rumble_r));
if (sscanf(argv[i], "%d,%d", &rumble_l, &rumble_r) == 2)
{
rumble_l = std::max(0, std::min(255, rumble_l));
rumble_r = std::max(0, std::min(255, rumble_r));
}
else
{
std::cout << "Error: " << argv[i-1] << " expected a argument in form INT,INT" << std::endl;
return EXIT_FAILURE;
}
}
else
{
@ -373,27 +408,33 @@ int main(int argc, char** argv)
{
if (strcmp(argv[i], "xbox") == 0)
{
forced_type = GAMEPAD_XBOX;
gamepad_type = GAMEPAD_XBOX;
}
else if (strcmp(argv[i], "xbox360") == 0)
{
forced_type = GAMEPAD_XBOX360;
gamepad_type = GAMEPAD_XBOX360;
}
else if (strcmp(argv[i], "xbox360-guitar") == 0)
{
forced_type = GAMEPAD_XBOX360_GUITAR;
gamepad_type = GAMEPAD_XBOX360_GUITAR;
}
else if (strcmp(argv[i], "xbox360-wireless") == 0)
{
forced_type = GAMEPAD_XBOX360_WIRELESS;
gamepad_type = GAMEPAD_XBOX360_WIRELESS;
}
else if (strcmp(argv[i], "xbox-dancemat") == 0)
{
forced_type = GAMEPAD_XBOX_MAT;
gamepad_type = GAMEPAD_XBOX_MAT;
}
else
{
std::cout << "Error: Unknown type: " << argv[i] << std::endl;
std::cout << "Error: unknown type: " << argv[i] << std::endl;
std::cout << "Possible types are:" << std::endl;
std::cout << " * xbox" << std::endl;
std::cout << " * xbox360" << std::endl;
std::cout << " * xbox360-guitar" << std::endl;
std::cout << " * xbox360-wireless" << std::endl;
std::cout << " * xbox360-dancemat" << std::endl;
return EXIT_FAILURE;
}
}
@ -482,7 +523,39 @@ int main(int argc, char** argv)
<< std::endl;
return EXIT_SUCCESS;
}
else if (strcmp(argv[i], "--list-controller") == 0 &&
else if (strcmp(argv[i], "--device") == 0 ||
strcmp(argv[i], "-d") == 0)
{
++i;
if (i < argc)
{
if (sscanf(argv[i], "%3s:%3s", busid, devid) == 2)
{
std::cout << " ***************************************" << std::endl;
std::cout << " *** WARNING *** WARNING *** WARNING ***" << std::endl;
std::cout << " ***************************************" << std::endl;
std::cout << "The '--device DEV' option should not be needed for normal use" << std::endl;
std::cout << "and might potentially be harmful when used on devices that" << std::endl;
std::cout << "are not a gamepad, use at your own risk and ensure that you" << std::endl;
std::cout << "are accessing the right device.\n" << std::endl;
std::cout << "If you have multiple gamepads and want to select a differnt" << std::endl;
std::cout << "one use the '-id N' option instead.\n" << std::endl;
std::cout << "Press Ctrl-c to exit and Enter to continue." << std::endl;
getchar();
}
else
{
std::cout << "Error: " << argv[i-1] << " expected a argument in form BUS:DEV (i.e. 006:003)" << std::endl;
return EXIT_FAILURE;
}
}
else
{
std::cout << "Error: " << argv[i-1] << " expected an argument" << std::endl;
return EXIT_FAILURE;
}
}
else if (strcmp(argv[i], "--list-controller") == 0 ||
strcmp(argv[i], "-L") == 0)
{
usb_init();
@ -519,19 +592,50 @@ int main(int argc, char** argv)
struct usb_device* dev = 0;
XPadDevice* dev_type = 0;
if (!find_xbox360_controller(controller_id, &dev, &dev_type))
if (busid[0] != '\0' && devid[0] != '\0')
{
std::cout << "No XBox360 Controller found" << std::endl;
if (gamepad_type == -1)
{
std::cout << "Error: --device BUS:DEV option must be used in combination with --type TYPE option" << std::endl;
exit(EXIT_FAILURE);
}
else
{
if (!find_controller_by_path(busid, devid, &dev))
{
std::cout << "Error: couldn't find device " << busid << ":" << devid << std::endl;
exit(EXIT_FAILURE);
}
}
}
else
{
if (!find_xbox360_controller(controller_id, &dev, &dev_type))
{
std::cout << "No XBox or XBox360 controller found" << std::endl;
exit(EXIT_FAILURE);
}
}
if (!dev)
{
std::cout << "No suitable USB device found, abort" << std::endl;
exit(EXIT_FAILURE);
}
else
{
// Could/should fork here to hande multiple controllers at once
if (forced_type != -1)
dev_type->type = static_cast<GamepadType>(forced_type);
if (gamepad_type == -1)
{
assert(dev_type);
gamepad_type = dev_type->type;
}
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->name % dev_type->idVendor % dev_type->idProduct << std::endl;
std::cout << "Controller Type: " << dev_type->type << std::endl;
% (dev_type ? dev_type->name : "unknown") % uint16_t(dev->descriptor.idVendor) % uint16_t(dev->descriptor.idProduct) << std::endl;
std::cout << "Controller Type: " << gamepad_type << std::endl;
std::cout << "Rumble Debug: " << (rumble ? "on" : "off") << std::endl;
std::cout << "Rumble Speed: " << "left: " << rumble_l << " right: " << rumble_r << std::endl;
std::cout << "LED Status: " << int(led) << std::endl;
@ -547,22 +651,22 @@ int main(int argc, char** argv)
std::cout << "Error claiming the interface: " << usb_strerror() << std::endl;
// Handle LED on XBox360 Controller
if (dev_type->type == GAMEPAD_XBOX360 ||
dev_type->type == GAMEPAD_XBOX360_GUITAR)
if (gamepad_type == GAMEPAD_XBOX360 ||
gamepad_type == GAMEPAD_XBOX360_GUITAR)
{
char ledcmd[] = {1, 3, led};
usb_interrupt_write(handle, 2, ledcmd, 3, 0);
}
// Switch of Rumble
if (dev_type->type == GAMEPAD_XBOX360)
if (gamepad_type == GAMEPAD_XBOX360)
{
char l = rumble_r; // light weight
char b = rumble_l; // big weight
char rumblecmd[] = { 0x00, 0x08, 0x00, b, l, 0x00, 0x00, 0x00 };
usb_interrupt_write(handle, 2, rumblecmd, 8, 0);
}
else if (dev_type->type == GAMEPAD_XBOX)
else if (gamepad_type == GAMEPAD_XBOX)
{
char l = rumble_l;
char b = rumble_r;
@ -580,7 +684,7 @@ int main(int argc, char** argv)
if (!no_uinput)
{
std::cout << "Starting uinput" << std::endl;
uinput = new uInput(dev_type->type, uinput_config);
uinput = new uInput(static_cast<GamepadType>(gamepad_type), uinput_config);
}
else
{
@ -629,7 +733,7 @@ int main(int argc, char** argv)
{
memcpy(old_data, data, 20);
if (dev_type->type == GAMEPAD_XBOX360_GUITAR)
if (gamepad_type == GAMEPAD_XBOX360_GUITAR)
{
XBox360GuitarMsg& msg = (XBox360GuitarMsg&)data;
if (verbose)
@ -637,7 +741,7 @@ int main(int argc, char** argv)
uinput->send(msg);
}
else if (dev_type->type == GAMEPAD_XBOX360)
else if (gamepad_type == GAMEPAD_XBOX360)
{
XBox360Msg& msg = (XBox360Msg&)data;
@ -655,7 +759,7 @@ int main(int argc, char** argv)
}
}
else if (dev_type->type == GAMEPAD_XBOX)
else if (gamepad_type == GAMEPAD_XBOX)
{
XBoxMsg& msg = (XBoxMsg&)data;
@ -710,7 +814,6 @@ int main(int argc, char** argv)
}
}
std::cout << "Done" << std::endl;
return 0;
}