mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
USB: Add evdev support for keyboardmania
This commit is contained in:
+3
-1
@@ -12,6 +12,8 @@
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox, bool scrollable = false); // linux/config-gtk.cpp
|
||||
|
||||
@@ -189,7 +189,7 @@ static void configureApi(GtkWidget* widget, gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox)
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox, bool scrollable)
|
||||
{
|
||||
GtkWidget *rs_hbox, *rs_label, *rs_cb;
|
||||
|
||||
@@ -199,10 +199,16 @@ GtkWidget* new_combobox(const char* label, GtkWidget* vbox)
|
||||
rs_label = gtk_label_new(label);
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_label, FALSE, TRUE, 5);
|
||||
gtk_label_set_justify(GTK_LABEL(rs_label), GTK_JUSTIFY_RIGHT);
|
||||
gtk_misc_set_alignment(GTK_MISC(rs_label), 1, 0.5);
|
||||
|
||||
rs_cb = gtk_combo_box_text_new();
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_cb, TRUE, TRUE, 5);
|
||||
if (!scrollable)
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), rs_cb, TRUE, TRUE, 5);
|
||||
else
|
||||
{
|
||||
GtkWidget* sw = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_container_add(GTK_CONTAINER(sw), rs_cb);
|
||||
gtk_box_pack_start(GTK_BOX(rs_hbox), sw, TRUE, TRUE, 5);
|
||||
}
|
||||
return rs_cb;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
|
||||
|
||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||
|
||||
namespace usb_eyetoy
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
|
||||
|
||||
namespace usb_hid
|
||||
{
|
||||
namespace evdev
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include "USB/dynlink/pulse.h"
|
||||
#endif
|
||||
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
|
||||
|
||||
namespace usb_mic
|
||||
{
|
||||
namespace audiodev_pulse
|
||||
|
||||
@@ -1316,7 +1316,7 @@ namespace usb_pad
|
||||
INVERTFORCES[port] = SendDlgItemMessage(hWnd, IDC_CHECK1, BM_GETCHECK, 0, 0);
|
||||
useRamp = !!SendDlgItemMessage(hWnd, IDC_CHECK3, BM_GETCHECK, 0, 0);
|
||||
GAINZ[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER4), TBM_GETPOS, 0, 0);
|
||||
FFMULTI[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER5), TBM_GETPOS, 0, 0);
|
||||
FFMULTI[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER5), TBM_GETPOS, 0, 0);
|
||||
}
|
||||
|
||||
void SaveDInputConfig(int port, const char* dev_type)
|
||||
@@ -1460,11 +1460,11 @@ namespace usb_pad
|
||||
struct DXDlgSettings s;
|
||||
s.port = port;
|
||||
s.dev_type = dev_type;
|
||||
if (strcmp(dev_type, "buzz_device") == 0)
|
||||
if (strcmp(dev_type, BuzzDevice::TypeName()) == 0)
|
||||
{
|
||||
return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DLG_BUZZ), h.hWnd, DxDialogProc, (LPARAM)&s);
|
||||
}
|
||||
if (strcmp(dev_type, "keyboardmania") == 0)
|
||||
if (strcmp(dev_type, KeyboardmaniaDevice::TypeName()) == 0)
|
||||
{
|
||||
return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DLG_KEYBOARDMANIA), h.hWnd, DxDialogProc, (LPARAM)&s);
|
||||
}
|
||||
|
||||
@@ -279,8 +279,8 @@ namespace usb_pad
|
||||
"BRIGHTNESS_ZERO", /* linux:244 (KEY_BRIGHTNESS_ZERO) */
|
||||
"DISPLAY_OFF", /* linux:245 (KEY_DISPLAY_OFF) */
|
||||
"WIMAX", /* linux:246 (KEY_WIMAX) */
|
||||
"247", /* linux:247 (unnamed) */
|
||||
"248", /* linux:248 (unnamed) */
|
||||
"RFKILL", /* linux:247 (KEY_RFKILL) */
|
||||
"MICMUTE", /* linux:248 (KEY_MICMUTE) */
|
||||
"249", /* linux:249 (unnamed) */
|
||||
"250", /* linux:250 (unnamed) */
|
||||
"251", /* linux:251 (unnamed) */
|
||||
@@ -556,15 +556,15 @@ namespace usb_pad
|
||||
"NUMERIC_9", /* linux:521 (KEY_NUMERIC_9) */
|
||||
"NUMERIC_STAR", /* linux:522 (KEY_NUMERIC_STAR) */
|
||||
"NUMERIC_POUND", /* linux:523 (KEY_NUMERIC_POUND) */
|
||||
"RFKILL", /* linux:524 (KEY_RFKILL) */
|
||||
"KEY_NUMERIC_A", /* linux:524 (KEY_NUMERIC_A) */
|
||||
};
|
||||
|
||||
static bool GetEventName(const char* dev_type, int map, int event, const char** name)
|
||||
static bool GetEventName(const char* dev_type, int map, int event, bool is_button, const char** name)
|
||||
{
|
||||
if (!name)
|
||||
return false;
|
||||
|
||||
if (map < JOY_STEERING || !strcmp(dev_type, BuzzDevice::TypeName()))
|
||||
if (is_button)
|
||||
{
|
||||
if (event < (int)key_to_str.size())
|
||||
{
|
||||
@@ -593,7 +593,7 @@ namespace usb_pad
|
||||
};
|
||||
AxisValue axisVal[ABS_MAX + 1]{};
|
||||
unsigned long absbit[NBITS(ABS_MAX)]{};
|
||||
struct axis_correct abs_correct[ABS_MAX]{};
|
||||
axis_correct abs_correct[ABS_MAX]{};
|
||||
|
||||
inverted = false;
|
||||
|
||||
@@ -616,9 +616,7 @@ namespace usb_pad
|
||||
while ((len = read(js.second.fd, &event, sizeof(event))) > 0)
|
||||
;
|
||||
|
||||
struct timeval timeout
|
||||
{
|
||||
};
|
||||
timeval timeout{};
|
||||
timeout.tv_sec = 5;
|
||||
int result = select(maxfd + 1, &fdset, NULL, NULL, &timeout);
|
||||
|
||||
@@ -744,6 +742,8 @@ namespace usb_pad
|
||||
int ret = 0;
|
||||
if (!strcmp(dev_type, BuzzDevice::TypeName()))
|
||||
ret = GtkBuzzConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs);
|
||||
else if (!strcmp(dev_type, KeyboardmaniaDevice::TypeName()))
|
||||
ret = GtkKeyboardmaniaConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs);
|
||||
else
|
||||
ret = GtkPadConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs);
|
||||
return ret;
|
||||
|
||||
@@ -108,7 +108,6 @@ namespace usb_pad
|
||||
}
|
||||
}
|
||||
}
|
||||
//quit:
|
||||
closedir(dirp);
|
||||
return false;
|
||||
}
|
||||
@@ -151,7 +150,7 @@ namespace usb_pad
|
||||
str.clear();
|
||||
str.str("");
|
||||
str << EVDEV_DIR << dp->d_name;
|
||||
std::string path = str.str();
|
||||
const std::string path = str.str();
|
||||
|
||||
auto it = std::find_if(list_cache.begin(), list_cache.end(),
|
||||
[&path](evdev_device& dev) {
|
||||
@@ -168,14 +167,14 @@ namespace usb_pad
|
||||
continue;
|
||||
}
|
||||
|
||||
//list_cache.push_back(std::make_pair(std::string(dp->d_name), path));
|
||||
|
||||
res = ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
|
||||
if (res < 0)
|
||||
Console.Warning("EVIOCGNAME");
|
||||
else
|
||||
{
|
||||
list_cache.push_back({buf, dp->d_name, path});
|
||||
evdev_device dev{buf, dp->d_name, path, {}};
|
||||
res = ioctl(fd, EVIOCGID, &dev.input_id);
|
||||
list_cache.push_back(dev);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@@ -183,7 +182,6 @@ namespace usb_pad
|
||||
}
|
||||
|
||||
list.assign(list_cache.begin(), list_cache.end());
|
||||
//quit:
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
@@ -220,7 +218,7 @@ namespace usb_pad
|
||||
//case ABS_Y: mWheelData.clutch = NORM(value, 0xFF); break; //no wheel on PS2 has one, afaik
|
||||
//case ABS_RX: mWheelData.axis_rx = NORM(event.value, 0xFF); break;
|
||||
case ABS_RY:
|
||||
//treat_me_like_ABS_RY:
|
||||
//treat_me_like_ABS_RY:
|
||||
mWheelData.throttle = 0xFF;
|
||||
mWheelData.brake = 0xFF;
|
||||
if (value < 0)
|
||||
@@ -230,18 +228,10 @@ namespace usb_pad
|
||||
break;
|
||||
case 0x80 | JOY_THROTTLE:
|
||||
case ABS_Z:
|
||||
/*if (mIsGamepad)
|
||||
mWheelData.brake = 0xFF - NORM(value, 0xFF);
|
||||
else*/
|
||||
mWheelData.throttle = device.cfg.inverted[1] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF);
|
||||
break;
|
||||
case 0x80 | JOY_BRAKE:
|
||||
case ABS_RZ:
|
||||
/*if (mIsGamepad)
|
||||
mWheelData.throttle = 0xFF - NORM(value, 0xFF);
|
||||
else if (mIsDualAnalog)
|
||||
goto treat_me_like_ABS_RY;
|
||||
else*/
|
||||
mWheelData.brake = device.cfg.inverted[2] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF);
|
||||
break;
|
||||
|
||||
@@ -323,9 +313,8 @@ namespace usb_pad
|
||||
break;
|
||||
|
||||
value = AxisCorrect(device.abs_correct[event.code], event.value);
|
||||
/*if (event.code == 0)
|
||||
event.code, device.axis_map[event.code] & ~0x80, event.value, value);
|
||||
*/
|
||||
//if (event.code == 0)
|
||||
// event.code, device.axis_map[event.code] & ~0x80, event.value, value);
|
||||
SetAxis(device, event.code, value);
|
||||
}
|
||||
break;
|
||||
@@ -333,7 +322,7 @@ namespace usb_pad
|
||||
{
|
||||
code = device.btn_map[event.code] != (uint16_t)-1 ? device.btn_map[event.code] : event.code;
|
||||
|
||||
if (mType == WT_BUZZ_CONTROLLER)
|
||||
if (mType == WT_BUZZ_CONTROLLER || mType == WT_KEYBOARDMANIA_CONTROLLER)
|
||||
{
|
||||
if (device.btn_map[event.code] != (uint16_t)-1)
|
||||
{
|
||||
@@ -568,7 +557,7 @@ namespace usb_pad
|
||||
}
|
||||
|
||||
if (joypath.empty() || !file_exists(joypath))
|
||||
goto quit;
|
||||
return 1;
|
||||
|
||||
int fd = -1;
|
||||
if ((fd = open(joypath.c_str(), O_RDWR | O_NONBLOCK)) < 0)
|
||||
@@ -584,16 +573,6 @@ namespace usb_pad
|
||||
int pid, vid;
|
||||
if ((mUseRawFF = FindHidraw(evphys, hid_dev, &vid, &pid)))
|
||||
{
|
||||
|
||||
// For safety, only allow Logitech (classic ffb) devices
|
||||
if (vid != 0x046D /* Logitech */ /*|| info.bustype != BUS_USB*/
|
||||
|| pid == 0xc262 /* G920 hid mode */
|
||||
|| pid == 0xc261 /* G920 xbox mode */
|
||||
)
|
||||
{
|
||||
mUseRawFF = 0;
|
||||
}
|
||||
|
||||
// check if still using hidraw and run the thread
|
||||
if (mUseRawFF && !mWriterThreadIsRunning)
|
||||
{
|
||||
@@ -637,13 +616,6 @@ namespace usb_pad
|
||||
continue;
|
||||
}
|
||||
|
||||
/*unsigned int version;
|
||||
if (ioctl(mHandle, EVIOCGVERSION, &version) < 0)
|
||||
{
|
||||
SysMessage("%s: Get version failed: %s\n", APINAME, strerror(errno));
|
||||
return false;
|
||||
}*/
|
||||
|
||||
int max_buttons = JOY_STEERING;
|
||||
switch (mType)
|
||||
{
|
||||
@@ -651,8 +623,13 @@ namespace usb_pad
|
||||
LoadBuzzMappings(mDevType, mPort, it.id, device.cfg);
|
||||
max_buttons = 20;
|
||||
break;
|
||||
case WT_KEYBOARDMANIA_CONTROLLER:
|
||||
max_buttons = 31;
|
||||
LoadMappings(mDevType, mPort, it.id, max_buttons, 0, device.cfg);
|
||||
break;
|
||||
default:
|
||||
LoadMappings(mDevType, mPort, it.id, device.cfg);
|
||||
max_buttons = JOY_STEERING;
|
||||
LoadMappings(mDevType, mPort, it.id, max_buttons, 3, device.cfg);
|
||||
if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN_ENABLED, b_gain))
|
||||
b_gain = 1;
|
||||
if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN, gain))
|
||||
@@ -715,12 +692,6 @@ namespace usb_pad
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < ABS_MAX; ++i)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i)
|
||||
{
|
||||
if (test_bit(i, keybit))
|
||||
@@ -763,10 +734,6 @@ namespace usb_pad
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
quit:
|
||||
Close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EvDevPad::Close()
|
||||
@@ -776,9 +743,12 @@ namespace usb_pad
|
||||
|
||||
if (mHidHandle != -1)
|
||||
{
|
||||
uint8_t reset[7] = {0};
|
||||
reset[0] = 0xF3; //stop forces
|
||||
write(mHidHandle, reset, sizeof(reset));
|
||||
if (mType <= WT_GT_FORCE)
|
||||
{
|
||||
uint8_t reset[7] = {0};
|
||||
reset[0] = 0xF3; //stop forces
|
||||
write(mHidHandle, reset, sizeof(reset));
|
||||
}
|
||||
close(mHidHandle);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
#pragma once
|
||||
#include <linux/joystick.h>
|
||||
#include <unistd.h>
|
||||
#include "Pcsx2Types.h"
|
||||
#include "USB/gtk.h"
|
||||
#include "USB/usb-pad/padproxy.h"
|
||||
#include "USB/configuration.h"
|
||||
@@ -31,10 +32,15 @@ struct evdev_device
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string path;
|
||||
struct {
|
||||
uint16_t bustype;
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t version;
|
||||
} input_id;
|
||||
};
|
||||
|
||||
typedef std::vector<evdev_device> device_list;
|
||||
GtkWidget* new_combobox(const char* label, GtkWidget* vbox);
|
||||
|
||||
namespace usb_pad
|
||||
{
|
||||
@@ -46,7 +52,6 @@ namespace usb_pad
|
||||
COL_NAME = 0,
|
||||
COL_PS2,
|
||||
COL_PC,
|
||||
COL_COLUMN_WIDTH,
|
||||
COL_BINDING,
|
||||
NUM_COLS
|
||||
};
|
||||
@@ -76,7 +81,7 @@ namespace usb_pad
|
||||
JOY_MAPS_COUNT
|
||||
};
|
||||
|
||||
static constexpr const char* JoystickMapNames[] = {
|
||||
constexpr const char* JoystickMapNames[]{
|
||||
"cross",
|
||||
"square",
|
||||
"circle",
|
||||
@@ -95,9 +100,10 @@ namespace usb_pad
|
||||
"right",
|
||||
"steering",
|
||||
"throttle",
|
||||
"brake"};
|
||||
"brake",
|
||||
};
|
||||
|
||||
static constexpr const char* buzz_map_names[] = {
|
||||
constexpr const char* buzz_map_names[]{
|
||||
"red",
|
||||
"yellow",
|
||||
"green",
|
||||
@@ -105,6 +111,40 @@ namespace usb_pad
|
||||
"blue",
|
||||
};
|
||||
|
||||
constexpr const char* kbdmania_key_labels[]{
|
||||
"C 1",
|
||||
"C# 1",
|
||||
"D 1",
|
||||
"D# 1",
|
||||
"E 1",
|
||||
"F 1",
|
||||
"F# 1",
|
||||
"",
|
||||
"G 1",
|
||||
"G# 1",
|
||||
"A 1",
|
||||
"A# 1",
|
||||
"B 1",
|
||||
"C 2",
|
||||
"Select",
|
||||
"",
|
||||
"C# 2",
|
||||
"D 2",
|
||||
"D# 2",
|
||||
"E 2",
|
||||
"F 2",
|
||||
"F# 2",
|
||||
"Start",
|
||||
"",
|
||||
"G 2",
|
||||
"G# 2",
|
||||
"A 2",
|
||||
"A# 2",
|
||||
"B 2",
|
||||
"Up",
|
||||
"Down",
|
||||
};
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x;
|
||||
@@ -128,7 +168,7 @@ namespace usb_pad
|
||||
|
||||
struct ApiCallbacks
|
||||
{
|
||||
bool (*get_event_name)(const char* dev_type, int map, int event, const char** name);
|
||||
bool (*get_event_name)(const char* dev_type, int map, int event, bool is_button, const char** name);
|
||||
void (*populate)(device_list& jsdata);
|
||||
bool (*poll)(const std::vector<std::pair<std::string, ConfigMapping>>& jsconf, std::string& dev_name, bool isaxis, int& value, bool& inverted, int& initial);
|
||||
};
|
||||
@@ -145,6 +185,7 @@ namespace usb_pad
|
||||
ApiCallbacks* cb;
|
||||
int use_hidraw_ff_pt;
|
||||
const char* dev_type;
|
||||
u32 max_axes, max_buttons;
|
||||
};
|
||||
|
||||
struct axis_correct
|
||||
@@ -167,8 +208,9 @@ namespace usb_pad
|
||||
|
||||
int GtkPadConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs);
|
||||
int GtkBuzzConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs);
|
||||
bool LoadMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg);
|
||||
bool SaveMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg);
|
||||
int GtkKeyboardmaniaConfigure(int port, const char* dev_type, const char* apititle, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs);
|
||||
bool LoadMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, ConfigMapping& cfg);
|
||||
bool SaveMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, const ConfigMapping& cfg);
|
||||
bool LoadBuzzMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg);
|
||||
bool SaveBuzzMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg);
|
||||
} // namespace evdev
|
||||
|
||||
@@ -32,10 +32,10 @@ namespace usb_pad
|
||||
#define JOYTYPE "joytype"
|
||||
#define CFG "cfg"
|
||||
|
||||
static bool GetEventName(const char* dev_type, int map, int event, const char** name)
|
||||
static bool GetEventName(const char* dev_type, int map, int event, bool is_button, const char** name)
|
||||
{
|
||||
static char buf[256] = {0};
|
||||
if (map < evdev::JOY_STEERING)
|
||||
if (is_button)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "Button %d", event);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ namespace usb_pad
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
//quit:
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
@@ -381,7 +380,7 @@ namespace usb_pad
|
||||
continue;
|
||||
}
|
||||
|
||||
LoadMappings(mDevType, mPort, device.name, device.cfg);
|
||||
LoadMappings(mDevType, mPort, device.name, 3, 16, device.cfg);
|
||||
|
||||
// Axis Mapping
|
||||
if (ioctl(device.cfg.fd, JSIOCGAXMAP, device.axis_map) < 0)
|
||||
@@ -394,16 +393,17 @@ namespace usb_pad
|
||||
if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
|
||||
for (int k = 0; k < count; k++)
|
||||
{
|
||||
for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++)
|
||||
for (int k = 0; k < count; k++)
|
||||
{
|
||||
if (k == device.cfg.controls[i])
|
||||
for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++)
|
||||
{
|
||||
device.axis_map[k] = 0x80 | i;
|
||||
if (i == JOY_STEERING)
|
||||
has_steering = true;
|
||||
if (k == device.cfg.controls[i])
|
||||
{
|
||||
device.axis_map[k] = 0x80 | i;
|
||||
if (i == JOY_STEERING)
|
||||
has_steering = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace usb_pad
|
||||
"Logitech Buzz(tm) Controller V1",
|
||||
"",
|
||||
"Logitech"};
|
||||
|
||||
static const USBDescStrings kbm_desc_strings = {
|
||||
"",
|
||||
"USB Multipurpose Controller",
|
||||
@@ -93,7 +94,7 @@ namespace usb_pad
|
||||
|
||||
std::list<std::string> KeyboardmaniaDevice::ListAPIs()
|
||||
{
|
||||
return PadDevice::ListAPIs();
|
||||
return {"evdev"};
|
||||
}
|
||||
|
||||
const TCHAR* KeyboardmaniaDevice::LongAPIName(const std::string& name)
|
||||
@@ -319,7 +320,6 @@ namespace usb_pad
|
||||
s->pad->Close();
|
||||
}
|
||||
|
||||
|
||||
void pad_reset_data(generic_data_t* d)
|
||||
{
|
||||
memset(d, 0, sizeof(generic_data_t));
|
||||
@@ -540,6 +540,28 @@ namespace usb_pad
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pad_init(PADState* s, int port, Pad* pad)
|
||||
{
|
||||
s->f.dev_subtype = pad->Type();
|
||||
s->pad = pad;
|
||||
s->port = port;
|
||||
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.klass.handle_attach = usb_desc_attach;
|
||||
s->dev.klass.handle_reset = pad_handle_reset;
|
||||
s->dev.klass.handle_control = pad_handle_control;
|
||||
s->dev.klass.handle_data = pad_handle_data;
|
||||
s->dev.klass.unrealize = pad_handle_destroy;
|
||||
s->dev.klass.open = pad_open;
|
||||
s->dev.klass.close = pad_close;
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = nullptr;
|
||||
|
||||
usb_desc_init(&s->dev);
|
||||
usb_ep_init(&s->dev);
|
||||
pad_handle_reset((USBDevice*)s);
|
||||
}
|
||||
|
||||
USBDevice* PadDevice::CreateDevice(int port)
|
||||
{
|
||||
std::string varApi;
|
||||
@@ -554,13 +576,13 @@ namespace usb_pad
|
||||
if (!proxy)
|
||||
{
|
||||
Console.WriteLn("USB: PAD: Invalid input API.\n");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Pad* pad = proxy->CreateObject(port, TypeName());
|
||||
|
||||
if (!pad)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
pad->Type((PS2WheelTypes)GetSelectedSubtype(std::make_pair(port, TypeName())));
|
||||
PADState* s = new PADState();
|
||||
@@ -610,23 +632,7 @@ namespace usb_pad
|
||||
if (usb_desc_parse_config(config_desc, config_desc_len, s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->f.dev_subtype = pad->Type();
|
||||
s->pad = pad;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.klass.handle_attach = usb_desc_attach;
|
||||
s->dev.klass.handle_reset = pad_handle_reset;
|
||||
s->dev.klass.handle_control = pad_handle_control;
|
||||
s->dev.klass.handle_data = pad_handle_data;
|
||||
s->dev.klass.unrealize = pad_handle_destroy;
|
||||
s->dev.klass.open = pad_open;
|
||||
s->dev.klass.close = pad_close;
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = s->desc.str[2]; //not really used
|
||||
s->port = port;
|
||||
|
||||
usb_desc_init(&s->dev);
|
||||
usb_ep_init(&s->dev);
|
||||
pad_handle_reset((USBDevice*)s);
|
||||
pad_init(s, port, pad);
|
||||
|
||||
return (USBDevice*)s;
|
||||
|
||||
@@ -682,13 +688,13 @@ namespace usb_pad
|
||||
if (!proxy)
|
||||
{
|
||||
Console.WriteLn("RBDK: Invalid input API.\n");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Pad* pad = proxy->CreateObject(port, TypeName());
|
||||
|
||||
if (!pad)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
pad->Type(WT_ROCKBAND1_DRUMKIT);
|
||||
PADState* s = new PADState();
|
||||
@@ -701,23 +707,7 @@ namespace usb_pad
|
||||
if (usb_desc_parse_config(rb1_config_descriptor, sizeof(rb1_config_descriptor), s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->f.dev_subtype = pad->Type();
|
||||
s->pad = pad;
|
||||
s->port = port;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.klass.handle_attach = usb_desc_attach;
|
||||
s->dev.klass.handle_reset = pad_handle_reset;
|
||||
s->dev.klass.handle_control = pad_handle_control;
|
||||
s->dev.klass.handle_data = pad_handle_data;
|
||||
s->dev.klass.unrealize = pad_handle_destroy;
|
||||
s->dev.klass.open = pad_open;
|
||||
s->dev.klass.close = pad_close;
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = s->desc.str[2];
|
||||
|
||||
usb_desc_init(&s->dev);
|
||||
usb_ep_init(&s->dev);
|
||||
pad_handle_reset((USBDevice*)s);
|
||||
pad_init(s, port, pad);
|
||||
|
||||
return (USBDevice*)s;
|
||||
|
||||
@@ -774,23 +764,7 @@ namespace usb_pad
|
||||
if (usb_desc_parse_config(buzz_config_descriptor, sizeof(buzz_config_descriptor), s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->f.dev_subtype = pad->Type();
|
||||
s->pad = pad;
|
||||
s->port = port;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.klass.handle_attach = usb_desc_attach;
|
||||
s->dev.klass.handle_reset = pad_handle_reset;
|
||||
s->dev.klass.handle_control = pad_handle_control;
|
||||
s->dev.klass.handle_data = pad_handle_data;
|
||||
s->dev.klass.unrealize = pad_handle_destroy;
|
||||
s->dev.klass.open = pad_open;
|
||||
s->dev.klass.close = pad_close;
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = s->desc.str[2];
|
||||
|
||||
usb_desc_init(&s->dev);
|
||||
usb_ep_init(&s->dev);
|
||||
pad_handle_reset((USBDevice*)s);
|
||||
pad_init(s, port, pad);
|
||||
|
||||
return (USBDevice*)s;
|
||||
|
||||
@@ -828,13 +802,13 @@ namespace usb_pad
|
||||
if (!proxy)
|
||||
{
|
||||
Console.WriteLn("usb-pad: %s: Invalid input API.", TypeName());
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Pad* pad = proxy->CreateObject(port, TypeName());
|
||||
|
||||
if (!pad)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
pad->Type(WT_KEYBOARDMANIA_CONTROLLER);
|
||||
PADState* s = new PADState();
|
||||
@@ -847,23 +821,7 @@ namespace usb_pad
|
||||
if (usb_desc_parse_config(kbm_config_descriptor, sizeof(kbm_config_descriptor), s->desc_dev) < 0)
|
||||
goto fail;
|
||||
|
||||
s->f.dev_subtype = pad->Type();
|
||||
s->pad = pad;
|
||||
s->port = port;
|
||||
s->dev.speed = USB_SPEED_FULL;
|
||||
s->dev.klass.handle_attach = usb_desc_attach;
|
||||
s->dev.klass.handle_reset = pad_handle_reset;
|
||||
s->dev.klass.handle_control = pad_handle_control;
|
||||
s->dev.klass.handle_data = pad_handle_data;
|
||||
s->dev.klass.unrealize = pad_handle_destroy;
|
||||
s->dev.klass.open = pad_open;
|
||||
s->dev.klass.close = pad_close;
|
||||
s->dev.klass.usb_desc = &s->desc;
|
||||
s->dev.klass.product_desc = s->desc.str[2];
|
||||
|
||||
usb_desc_init(&s->dev);
|
||||
usb_ep_init(&s->dev);
|
||||
pad_handle_reset((USBDevice*)s);
|
||||
pad_init(s, port, pad);
|
||||
|
||||
return (USBDevice*)s;
|
||||
|
||||
|
||||
+12
-10
@@ -109,7 +109,6 @@ namespace usb_pad
|
||||
{
|
||||
return {};
|
||||
}
|
||||
static void Initialize();
|
||||
};
|
||||
|
||||
class SeamicDevice
|
||||
@@ -475,27 +474,30 @@ namespace usb_pad
|
||||
static const int HATS_8TO4[] = {PAD_HAT_N, PAD_HAT_E, PAD_HAT_S, PAD_HAT_W};
|
||||
|
||||
#define PAD_VID 0x046D
|
||||
#define PAD_PID 0xCA03 //black MOMO
|
||||
#define PAD_MOMO 0xCA03 //black MOMO
|
||||
#define GENERIC_PID 0xC294 //actually Driving Force aka PID that most logitech wheels initially report
|
||||
#define PID_DF 0xC294
|
||||
#define PID_DFP 0xC298 //SELECT + R3 + RIGHT SHIFT PADDLE (R1) ???
|
||||
#define PID_DFGT 0xC29A
|
||||
#define PID_FORMULA 0xC202 //Yellow Wingman Formula
|
||||
#define PID_FGP 0xC20E //Formula GP (maybe GT FORCE LPRC-1000)
|
||||
#define PID_FFGP 0xC293 // Formula Force GP
|
||||
#define PID_GTF 0xC293 // as is Formula Force GP
|
||||
#define PID_G25 0xC299 // OutRun 2 (jp) supports it apparently
|
||||
#define PID_FGP 0xC20E //Formula GP (maybe GT FORCE LPRC-1000)
|
||||
#define PID_FFGP 0xC293 // Formula Force GP
|
||||
#define PID_GTF 0xC293 // as is Formula Force GP
|
||||
#define PID_G25 0xC299 // OutRun 2 (jp) supports it apparently
|
||||
#define PID_G27 0xC29B
|
||||
#define MAX_BUTTONS 32
|
||||
#define MAX_AXES 7 //random 7: axes + hatswitch
|
||||
#define MAX_JOYS 32
|
||||
#define PAD_LG_FFB_WHITELIST \
|
||||
PAD_MOMO, PID_DF, PID_DFP, PID_DFGT, PID_FORMULA, PID_FGP, PID_FFGP, PID_GTF, PID_G25, PID_G27
|
||||
|
||||
/**
|
||||
linux hid-lg4ff.c
|
||||
http://www.spinics.net/lists/linux-input/msg16570.html
|
||||
Every Logitech wheel reports itself as generic Logitech Driving Force wheel (VID 046d, PID c294). This is done to ensure that the
|
||||
wheel will work on every USB HID-aware system even when no Logitech driver is available. It however limits the capabilities of the
|
||||
wheel - range is limited to 200 degrees, G25/G27 don't report the clutch pedal and there is only one combined axis for throttle and
|
||||
brake. The switch to native mode is done via hardware-specific command which is different for each wheel. When the wheel
|
||||
Every Logitech wheel reports itself as generic Logitech Driving Force wheel (VID 046d, PID c294). This is done to ensure that the
|
||||
wheel will work on every USB HID-aware system even when no Logitech driver is available. It however limits the capabilities of the
|
||||
wheel - range is limited to 200 degrees, G25/G27 don't report the clutch pedal and there is only one combined axis for throttle and
|
||||
brake. The switch to native mode is done via hardware-specific command which is different for each wheel. When the wheel
|
||||
receives such command, it simulates reconnect and reports to the OS with its actual PID.
|
||||
Currently not emulating reattachment. Any games that expect to?
|
||||
**/
|
||||
|
||||
Reference in New Issue
Block a user