add support for the saitek p3600
This commit is contained in:
parent
8e9fb6b40d
commit
a350404619
6 changed files with 297 additions and 0 deletions
|
@ -24,6 +24,7 @@
|
||||||
#include "generic_usb_controller.hpp"
|
#include "generic_usb_controller.hpp"
|
||||||
#include "playstation3_usb_controller.hpp"
|
#include "playstation3_usb_controller.hpp"
|
||||||
#include "saitek_p2500_controller.hpp"
|
#include "saitek_p2500_controller.hpp"
|
||||||
|
#include "saitek_p3600_controller.hpp"
|
||||||
#include "xbox360_controller.hpp"
|
#include "xbox360_controller.hpp"
|
||||||
#include "xbox360_wireless_controller.hpp"
|
#include "xbox360_wireless_controller.hpp"
|
||||||
#include "xbox_controller.hpp"
|
#include "xbox_controller.hpp"
|
||||||
|
@ -68,6 +69,9 @@ ControllerFactory::create(const XPadDevice& dev_type, libusb_device* dev, const
|
||||||
case GAMEPAD_SAITEK_P2500:
|
case GAMEPAD_SAITEK_P2500:
|
||||||
return ControllerPtr(new SaitekP2500Controller(dev, opts.detach_kernel_driver));
|
return ControllerPtr(new SaitekP2500Controller(dev, opts.detach_kernel_driver));
|
||||||
|
|
||||||
|
case GAMEPAD_SAITEK_P3600:
|
||||||
|
return ControllerPtr(new SaitekP3600Controller(dev, opts.detach_kernel_driver));
|
||||||
|
|
||||||
case GAMEPAD_PLAYSTATION3_USB:
|
case GAMEPAD_PLAYSTATION3_USB:
|
||||||
return ControllerPtr(new Playstation3USBController(dev, opts.detach_kernel_driver));
|
return ControllerPtr(new Playstation3USBController(dev, opts.detach_kernel_driver));
|
||||||
|
|
||||||
|
@ -132,6 +136,10 @@ ControllerFactory::create_multiple(const XPadDevice& dev_type, libusb_device* de
|
||||||
case GAMEPAD_SAITEK_P2500:
|
case GAMEPAD_SAITEK_P2500:
|
||||||
lst.push_back(ControllerPtr(new SaitekP2500Controller(dev, opts.detach_kernel_driver)));
|
lst.push_back(ControllerPtr(new SaitekP2500Controller(dev, opts.detach_kernel_driver)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GAMEPAD_SAITEK_P3600:
|
||||||
|
lst.push_back(ControllerPtr(new SaitekP3600Controller(dev, opts.detach_kernel_driver)));
|
||||||
|
break;
|
||||||
|
|
||||||
case GAMEPAD_PLAYSTATION3_USB:
|
case GAMEPAD_PLAYSTATION3_USB:
|
||||||
lst.push_back(ControllerPtr(new Playstation3USBController(dev, opts.detach_kernel_driver)));
|
lst.push_back(ControllerPtr(new Playstation3USBController(dev, opts.detach_kernel_driver)));
|
||||||
|
|
232
src/saitek_p3600_controller.cpp
Normal file
232
src/saitek_p3600_controller.cpp
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
** Xbox/Xbox360 USB Gamepad Userspace Driver
|
||||||
|
** Copyright (C) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||||
|
**
|
||||||
|
** 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "saitek_p3600_controller.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "helper.hpp"
|
||||||
|
#include "usb_helper.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
struct SaitekP3600Msg
|
||||||
|
{
|
||||||
|
int dummy :8; // data[0]
|
||||||
|
|
||||||
|
int x1 :8; // data[1]
|
||||||
|
int y1 :8; // data[2]
|
||||||
|
|
||||||
|
int x2 :8; // data[3]
|
||||||
|
int y2 :8; // data[4]
|
||||||
|
|
||||||
|
// data[5]
|
||||||
|
int trigger_analog :6;
|
||||||
|
|
||||||
|
unsigned int x :1;
|
||||||
|
unsigned int a :1;
|
||||||
|
|
||||||
|
// data[6]
|
||||||
|
unsigned int b :1;
|
||||||
|
unsigned int y :1;
|
||||||
|
|
||||||
|
unsigned int lb :1;
|
||||||
|
unsigned int rb :1;
|
||||||
|
unsigned int lt :1;
|
||||||
|
unsigned int rt :1;
|
||||||
|
|
||||||
|
unsigned int back :1;
|
||||||
|
unsigned int start :1;
|
||||||
|
|
||||||
|
// data[7]
|
||||||
|
unsigned int thumb_l :1;
|
||||||
|
unsigned int thumb_r :1;
|
||||||
|
|
||||||
|
unsigned int fps :1;
|
||||||
|
unsigned int fps_toggle :1;
|
||||||
|
|
||||||
|
unsigned int dpad :4;
|
||||||
|
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
SaitekP3600Controller::SaitekP3600Controller(libusb_device* dev, bool try_detach) :
|
||||||
|
USBController(dev),
|
||||||
|
left_rumble(-1),
|
||||||
|
right_rumble(-1)
|
||||||
|
{
|
||||||
|
usb_claim_interface(0, try_detach);
|
||||||
|
usb_submit_read(1, sizeof(SaitekP3600Msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
SaitekP3600Controller::~SaitekP3600Controller()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaitekP3600Controller::set_rumble_real(uint8_t left, uint8_t right)
|
||||||
|
{
|
||||||
|
// not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SaitekP3600Controller::set_led_real(uint8_t status)
|
||||||
|
{
|
||||||
|
// not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fix_int(int num) {
|
||||||
|
if (num < 0) {
|
||||||
|
return 128 + num;
|
||||||
|
} else {
|
||||||
|
return num - 127;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int
|
||||||
|
fix_int_6(int num) {
|
||||||
|
if (num < 0) {
|
||||||
|
return 32 + num;
|
||||||
|
} else {
|
||||||
|
return num - 31;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_trigger_val(bool digital, int analog) {
|
||||||
|
if (digital) {
|
||||||
|
if (analog > 4) {
|
||||||
|
return analog;
|
||||||
|
} else {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SaitekP3600Controller::parse(uint8_t* data, int len, XboxGenericMsg* msg_out)
|
||||||
|
{
|
||||||
|
if (len == sizeof(SaitekP3600Msg))
|
||||||
|
{
|
||||||
|
SaitekP3600Msg msg_in;
|
||||||
|
memcpy(&msg_in, data, sizeof(SaitekP3600Msg));
|
||||||
|
|
||||||
|
// Debug code, print packet as a binary string
|
||||||
|
//uint64_t dta = *(uint64_t*)data;
|
||||||
|
//std::cout << std::bitset<64>(dta) << std::endl;
|
||||||
|
|
||||||
|
memset(msg_out, 0, sizeof(*msg_out));
|
||||||
|
msg_out->type = XBOX_MSG_XBOX360;
|
||||||
|
|
||||||
|
msg_out->xbox360.a = msg_in.a;
|
||||||
|
msg_out->xbox360.b = msg_in.b;
|
||||||
|
msg_out->xbox360.x = msg_in.x;
|
||||||
|
msg_out->xbox360.y = msg_in.y;
|
||||||
|
|
||||||
|
msg_out->xbox360.lb = msg_in.lb;
|
||||||
|
msg_out->xbox360.rb = msg_in.rb;
|
||||||
|
|
||||||
|
// Digital switch triggers at 4
|
||||||
|
int trigger_analog = fix_int_6(msg_in.trigger_analog);
|
||||||
|
msg_out->xbox360.lt = get_trigger_val(msg_in.lt == 1, trigger_analog) * 8;
|
||||||
|
msg_out->xbox360.rt = get_trigger_val(msg_in.rt == 1, -trigger_analog) * 8;
|
||||||
|
|
||||||
|
msg_out->xbox360.start = msg_in.start;
|
||||||
|
msg_out->xbox360.back = msg_in.back;
|
||||||
|
msg_out->xbox360.guide = msg_in.fps;
|
||||||
|
|
||||||
|
msg_out->xbox360.thumb_l = msg_in.thumb_l;
|
||||||
|
msg_out->xbox360.thumb_r = msg_in.thumb_r;
|
||||||
|
|
||||||
|
msg_out->xbox360.x1 = scale_8to16(fix_int(msg_in.x1));
|
||||||
|
msg_out->xbox360.y1 = scale_8to16(-fix_int(msg_in.y1));
|
||||||
|
|
||||||
|
msg_out->xbox360.x2 = scale_8to16(fix_int(msg_in.x2));
|
||||||
|
msg_out->xbox360.y2 = scale_8to16(-fix_int(msg_in.y2));
|
||||||
|
|
||||||
|
printf("%d \n", fix_int_6(msg_in.trigger_analog));
|
||||||
|
|
||||||
|
switch(msg_in.dpad)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
msg_out->xbox360.dpad_up = 1;
|
||||||
|
msg_out->xbox360.dpad_down = 0;
|
||||||
|
msg_out->xbox360.dpad_left = 0;
|
||||||
|
msg_out->xbox360.dpad_right = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
msg_out->xbox360.dpad_up = 1;
|
||||||
|
msg_out->xbox360.dpad_down = 0;
|
||||||
|
msg_out->xbox360.dpad_left = 0;
|
||||||
|
msg_out->xbox360.dpad_right = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
msg_out->xbox360.dpad_up = 0;
|
||||||
|
msg_out->xbox360.dpad_down = 0;
|
||||||
|
msg_out->xbox360.dpad_left = 0;
|
||||||
|
msg_out->xbox360.dpad_right = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
msg_out->xbox360.dpad_up = 0;
|
||||||
|
msg_out->xbox360.dpad_down = 1;
|
||||||
|
msg_out->xbox360.dpad_left = 0;
|
||||||
|
msg_out->xbox360.dpad_right = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
msg_out->xbox360.dpad_up = 0;
|
||||||
|
msg_out->xbox360.dpad_down = 1;
|
||||||
|
msg_out->xbox360.dpad_left = 0;
|
||||||
|
msg_out->xbox360.dpad_right = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
msg_out->xbox360.dpad_up = 0;
|
||||||
|
msg_out->xbox360.dpad_down = 1;
|
||||||
|
msg_out->xbox360.dpad_left = 1;
|
||||||
|
msg_out->xbox360.dpad_right = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
msg_out->xbox360.dpad_up = 0;
|
||||||
|
msg_out->xbox360.dpad_down = 0;
|
||||||
|
msg_out->xbox360.dpad_left = 1;
|
||||||
|
msg_out->xbox360.dpad_right = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
msg_out->xbox360.dpad_up = 1;
|
||||||
|
msg_out->xbox360.dpad_down = 0;
|
||||||
|
msg_out->xbox360.dpad_left = 1;
|
||||||
|
msg_out->xbox360.dpad_right = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
48
src/saitek_p3600_controller.hpp
Normal file
48
src/saitek_p3600_controller.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
** Xbox/Xbox360 USB Gamepad Userspace Driver
|
||||||
|
** Copyright (C) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||||
|
**
|
||||||
|
** 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_SAITEK_P3600_CONTROLLER_HPP
|
||||||
|
#define HEADER_SAITEK_P3600_CONTROLLER_HPP
|
||||||
|
|
||||||
|
#include <libusb.h>
|
||||||
|
#include "xboxmsg.hpp"
|
||||||
|
#include "usb_controller.hpp"
|
||||||
|
|
||||||
|
class SaitekP3600Controller : public USBController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int left_rumble;
|
||||||
|
int right_rumble;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SaitekP3600Controller(libusb_device* dev, bool try_detach);
|
||||||
|
~SaitekP3600Controller();
|
||||||
|
|
||||||
|
void set_rumble_real(uint8_t left, uint8_t right);
|
||||||
|
void set_led_real(uint8_t status);
|
||||||
|
|
||||||
|
bool parse(uint8_t* data, int len, XboxGenericMsg* msg_out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SaitekP3600Controller(const SaitekP3600Controller&);
|
||||||
|
SaitekP3600Controller& operator=(const SaitekP3600Controller&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -67,6 +67,9 @@ std::string gamepadtype_to_string(const GamepadType& type)
|
||||||
case GAMEPAD_SAITEK_P2500:
|
case GAMEPAD_SAITEK_P2500:
|
||||||
return "saitek-p2500";
|
return "saitek-p2500";
|
||||||
|
|
||||||
|
case GAMEPAD_SAITEK_P3600:
|
||||||
|
return "saitek-p3600";
|
||||||
|
|
||||||
case GAMEPAD_PLAYSTATION3_USB:
|
case GAMEPAD_PLAYSTATION3_USB:
|
||||||
return "playstation3-usb";
|
return "playstation3-usb";
|
||||||
|
|
||||||
|
@ -92,6 +95,7 @@ std::string gamepadtype_to_macro_string(const GamepadType& type)
|
||||||
case GAMEPAD_FIRESTORM: return "GAMEPAD_FIRESTORM";
|
case GAMEPAD_FIRESTORM: return "GAMEPAD_FIRESTORM";
|
||||||
case GAMEPAD_FIRESTORM_VSB: return "GAMEPAD_FIRESTORM_VSB";
|
case GAMEPAD_FIRESTORM_VSB: return "GAMEPAD_FIRESTORM_VSB";
|
||||||
case GAMEPAD_SAITEK_P2500: return "GAMEPAD_SAITEK_P2500";
|
case GAMEPAD_SAITEK_P2500: return "GAMEPAD_SAITEK_P2500";
|
||||||
|
case GAMEPAD_SAITEK_P3600: return "GAMEPAD_SAITEK_P3600";
|
||||||
case GAMEPAD_PLAYSTATION3_USB: return "GAMEPAD_PLAYSTATION3_USB";
|
case GAMEPAD_PLAYSTATION3_USB: return "GAMEPAD_PLAYSTATION3_USB";
|
||||||
case GAMEPAD_GENERIC_USB: return "GAMEPAD_GENERIC_USB";
|
case GAMEPAD_GENERIC_USB: return "GAMEPAD_GENERIC_USB";
|
||||||
default:
|
default:
|
||||||
|
@ -130,6 +134,9 @@ std::ostream& operator<<(std::ostream& out, const GamepadType& type)
|
||||||
case GAMEPAD_SAITEK_P2500:
|
case GAMEPAD_SAITEK_P2500:
|
||||||
return out << "Saitek P2500";
|
return out << "Saitek P2500";
|
||||||
|
|
||||||
|
case GAMEPAD_SAITEK_P3600:
|
||||||
|
return out << "Saitek P3600";
|
||||||
|
|
||||||
case GAMEPAD_PLAYSTATION3_USB:
|
case GAMEPAD_PLAYSTATION3_USB:
|
||||||
return out << "Playstation 3 USB";
|
return out << "Playstation 3 USB";
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ enum GamepadType {
|
||||||
GAMEPAD_FIRESTORM,
|
GAMEPAD_FIRESTORM,
|
||||||
GAMEPAD_FIRESTORM_VSB,
|
GAMEPAD_FIRESTORM_VSB,
|
||||||
GAMEPAD_SAITEK_P2500,
|
GAMEPAD_SAITEK_P2500,
|
||||||
|
GAMEPAD_SAITEK_P3600,
|
||||||
GAMEPAD_PLAYSTATION3_USB,
|
GAMEPAD_PLAYSTATION3_USB,
|
||||||
GAMEPAD_GENERIC_USB
|
GAMEPAD_GENERIC_USB
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,6 +121,7 @@ XPadDevice xpad_devices[] = {
|
||||||
{ GAMEPAD_FIRESTORM_VSB, 0x044f, 0xb312, "ThrustMaster, Inc. Firestorm Dual Power (vs b)" },
|
{ GAMEPAD_FIRESTORM_VSB, 0x044f, 0xb312, "ThrustMaster, Inc. Firestorm Dual Power (vs b)" },
|
||||||
|
|
||||||
{ GAMEPAD_SAITEK_P2500, 0x06a3, 0xff0c, "Saitek P2500" },
|
{ GAMEPAD_SAITEK_P2500, 0x06a3, 0xff0c, "Saitek P2500" },
|
||||||
|
{ GAMEPAD_SAITEK_P3600, 0x06a3, 0xf51a, "Saitek P3600 (Cyborg Rumble)" },
|
||||||
|
|
||||||
{ GAMEPAD_PLAYSTATION3_USB, 0x054c, 0x0268, "PLAYSTATION(R)3 Controller" }
|
{ GAMEPAD_PLAYSTATION3_USB, 0x054c, 0x0268, "PLAYSTATION(R)3 Controller" }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue