Skip to content

feat(Flydigi): Add support for flydigi vader 3/4 pro #308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Fabianoshz
Copy link

This should add support for both flydigi vader 3 and 4.

Fixes #208

@Fabianoshz Fabianoshz force-pushed the add-flydigi-vader-pro-support branch from 75aa6d7 to 4fac759 Compare March 5, 2025 10:38
@blindedone1458
Copy link
Contributor

@Fabianoshz I think instead of doing all those remappings in the InputPlumber CapabilityMap, the xpad patch you are using should be updated so the Flydigi paddles match the Xbox Elite paddle mappings.
I've been using a Vader 3 Pro with xpad and this patch below based on cprn's patch here: paroj/xpad#268 (comment)

diff --git a/xpad.c b/xpad.c
index d5a016e..0e8f73f 100644
--- a/xpad.c
+++ b/xpad.c
@@ -95,6 +95,7 @@
 #define MAP_SELECT_BUTTON		(1 << 3)
 #define MAP_PADDLES			(1 << 4)
 #define MAP_PROFILE_BUTTON		(1 << 5)
+#define MAP_FLYDIGI_BUTTONS		(1 << 6)
 
 #define DANCEPAD_MAP_CONFIG	(MAP_DPAD_TO_BUTTONS |			\
 				MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
@@ -421,6 +422,19 @@ static const struct xpad_device {
 	{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
 };
 
+// A "flavor" is an aftermarket variant of an existing model supporting
+// additional features.
+static const struct xpad_flavor {
+	u16 idVendor;
+	u16 idProduct;
+	char *product;
+	u8 mapping;
+} xpad_flavor[] = {
+	{ 0x045e, 0x028e, "Flydigi VADER3", MAP_PADDLES | MAP_FLYDIGI_BUTTONS },
+	{ 0x045e, 0x028e, "Flydigi VADER4", MAP_PADDLES | MAP_FLYDIGI_BUTTONS },
+	{ 0x0000, 0x0000, NULL, 0 }
+};
+
 /* buttons shared with xbox and xbox360 */
 static const signed short xpad_common_btn[] = {
 	BTN_A, BTN_B, BTN_X, BTN_Y,			/* "analog" buttons */
@@ -484,6 +498,13 @@ static const struct {int x; int y; } dpad_mapping[] = {
 	{0, 0}
 };
 
+/* used for extra buttons in addition to paddles on Flydigi Vader Pro 3*/
+static const signed short xpad_btn_extra[] = {
+	BTN_TRIGGER_HAPPY9, BTN_TRIGGER_HAPPY10, /* Z, C face buttons */
+	BTN_TRIGGER_HAPPY11,			/* circle */
+	-1						/* terminating entry */
+};
+
 /*
  * Xbox 360 has a vendor-specific class, so we cannot match it with only
  * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
@@ -940,6 +961,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
  *
  *	The used report descriptor was taken from:
  *		http://www.free60.org/wiki/Gamepad
+ *	Packet length for valid data is 20 bytes.
  */
 
 static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
@@ -1012,6 +1034,17 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
 		input_report_abs(dev, ABS_RZ, data[5]);
 	}
 
+	/* Additional buttons for Flydigi Vader Pro 3 presenting as 360 pad. */
+	if (xpad->mapping & MAP_FLYDIGI_BUTTONS) {
+		input_report_key(dev, BTN_TRIGGER_HAPPY10, data[19] & BIT(0));   // C
+		input_report_key(dev, BTN_TRIGGER_HAPPY9, data[19] & BIT(1));  // Z
+		input_report_key(dev, BTN_TRIGGER_HAPPY8, data[19] & BIT(3));   // Leftmost paddle (M2)
+		input_report_key(dev, BTN_TRIGGER_HAPPY7, data[19] & BIT(5));   // Second to leftmost (M4)
+		input_report_key(dev, BTN_TRIGGER_HAPPY5, data[19] & BIT(4));   // Second to rightmost (M3)
+		input_report_key(dev, BTN_TRIGGER_HAPPY6, data[19] & BIT(2));   // Rightmost paddle (M1)
+		input_report_key(dev, BTN_TRIGGER_HAPPY11, data[20] & BIT(0));  // Circle
+	}
+
 	input_sync(dev);
 
 	/* XBOX360W controllers can't be turned off without driver assistance */
@@ -2246,6 +2279,13 @@ static int xpad_init_input(struct usb_xpad *xpad)
 			input_set_capability(input_dev, EV_KEY, xpad_btn_paddles[i]);
 	}
 
+	/* set up extra face buttons if the controller has them */
+	if (xpad->mapping & MAP_FLYDIGI_BUTTONS) {
+		for (i = 0; xpad_btn_extra[i] >= 0; i++) {
+			input_set_capability(input_dev, EV_KEY, xpad_btn_extra[i]);
+		}
+	}
+
 	/*
 	 * This should be a simple else block. However historically
 	 * xbox360w has mapped DPAD to buttons while xbox360 did not. This
@@ -2300,7 +2340,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_xpad *xpad;
 	struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
-	int i, error;
+	int i, j, error;
 
 	if (intf->cur_altsetting->desc.bNumEndpoints != 2)
 		return -ENODEV;
@@ -2334,6 +2374,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	xpad->udev = udev;
 	xpad->intf = intf;
 	xpad->mapping = xpad_device[i].mapping;
+
+	if (udev->product) {
+		for(j = 0; xpad_flavor[j].idVendor; j++) {
+			if (!strcmp(udev->product, xpad_flavor[j].product)) {
+				xpad->mapping |= xpad_flavor[j].mapping;
+				break;
+			}
+		}
+	}
+
 	xpad->xtype = xpad_device[i].xtype;
 	xpad->name = xpad_device[i].name;
 	xpad->quirks = xpad_device[i].quirks;

@belozer
Copy link

belozer commented Mar 5, 2025

@blindedone1458 Thanks, with this patch, I see that the paddle buttons is working (via steam). Apex 4

But what to do about the Share button? Because Series controllers have it.

@Fabianoshz
Copy link
Author

@blindedone1458 tbh I've set this up months ago and didn't bothered after that, having them being recognized a xbox elite could be good but it depends on ends up being merged on xpad.

My guess is that if you patch works we could maybe close this in favor of that and people can revisit this in the future in case the original patch gets merged for whatever reason.

@blindedone1458
Copy link
Contributor

For the Share button, are you referring to the Circle button? I honestly hadn't even considered the button as something that could be mapped originally (since it wasn't really doing much beyond controller functions) without Flydigi mapping software. I just made a change to the xpad patch to map it to a Share button:

diff --git a/xpad.c b/xpad.c
index d5a016e..0e8f73f 100644
--- a/xpad.c
+++ b/xpad.c
@@ -95,6 +95,7 @@
 #define MAP_SELECT_BUTTON		(1 << 3)
 #define MAP_PADDLES			(1 << 4)
 #define MAP_PROFILE_BUTTON		(1 << 5)
+#define MAP_FLYDIGI_BUTTONS		(1 << 6)
 
 #define DANCEPAD_MAP_CONFIG	(MAP_DPAD_TO_BUTTONS |			\
 				MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
@@ -421,6 +422,19 @@ static const struct xpad_device {
 	{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
 };
 
+// A "flavor" is an aftermarket variant of an existing model supporting
+// additional features.
+static const struct xpad_flavor {
+	u16 idVendor;
+	u16 idProduct;
+	char *product;
+	u8 mapping;
+} xpad_flavor[] = {
+	{ 0x045e, 0x028e, "Flydigi VADER3", MAP_PADDLES | MAP_FLYDIGI_BUTTONS },
+	{ 0x045e, 0x028e, "Flydigi VADER4", MAP_PADDLES | MAP_FLYDIGI_BUTTONS },
+	{ 0x0000, 0x0000, NULL, 0 }
+};
+
 /* buttons shared with xbox and xbox360 */
 static const signed short xpad_common_btn[] = {
 	BTN_A, BTN_B, BTN_X, BTN_Y,			/* "analog" buttons */
@@ -484,6 +498,13 @@ static const struct {int x; int y; } dpad_mapping[] = {
 	{0, 0}
 };
 
+/* used for extra buttons in addition to paddles on Flydigi Vader Pro 3*/
+static const signed short xpad_btn_extra[] = {
+	BTN_TRIGGER_HAPPY9, BTN_TRIGGER_HAPPY10, /* Z, C face buttons */
+	KEY_RECORD,			/* circle */
+	-1						/* terminating entry */
+};
+
 /*
  * Xbox 360 has a vendor-specific class, so we cannot match it with only
  * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
@@ -940,6 +961,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
  *
  *	The used report descriptor was taken from:
  *		http://www.free60.org/wiki/Gamepad
+ *	Packet length for valid data is 20 bytes.
  */
 
 static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
@@ -1012,6 +1034,17 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
 		input_report_abs(dev, ABS_RZ, data[5]);
 	}
 
+	/* Additional buttons for Flydigi Vader Pro 3 presenting as 360 pad. */
+	if (xpad->mapping & MAP_FLYDIGI_BUTTONS) {
+		input_report_key(dev, BTN_TRIGGER_HAPPY10, data[19] & BIT(0));   // C
+		input_report_key(dev, BTN_TRIGGER_HAPPY9, data[19] & BIT(1));  // Z
+		input_report_key(dev, BTN_TRIGGER_HAPPY8, data[19] & BIT(3));   // Leftmost paddle (M2)
+		input_report_key(dev, BTN_TRIGGER_HAPPY7, data[19] & BIT(5));   // Second to leftmost (M4)
+		input_report_key(dev, BTN_TRIGGER_HAPPY5, data[19] & BIT(4));   // Second to rightmost (M3)
+		input_report_key(dev, BTN_TRIGGER_HAPPY6, data[19] & BIT(2));   // Rightmost paddle (M1)
+		input_report_key(dev, KEY_RECORD, data[20] & BIT(0));  // Circle
+	}
+
 	input_sync(dev);
 
 	/* XBOX360W controllers can't be turned off without driver assistance */
@@ -2246,6 +2279,13 @@ static int xpad_init_input(struct usb_xpad *xpad)
 			input_set_capability(input_dev, EV_KEY, xpad_btn_paddles[i]);
 	}
 
+	/* set up extra face buttons if the controller has them */
+	if (xpad->mapping & MAP_FLYDIGI_BUTTONS) {
+		for (i = 0; xpad_btn_extra[i] >= 0; i++) {
+			input_set_capability(input_dev, EV_KEY, xpad_btn_extra[i]);
+		}
+	}
+
 	/*
 	 * This should be a simple else block. However historically
 	 * xbox360w has mapped DPAD to buttons while xbox360 did not. This
@@ -2300,7 +2340,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_xpad *xpad;
 	struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
-	int i, error;
+	int i, j, error;
 
 	if (intf->cur_altsetting->desc.bNumEndpoints != 2)
 		return -ENODEV;
@@ -2334,6 +2374,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	xpad->udev = udev;
 	xpad->intf = intf;
 	xpad->mapping = xpad_device[i].mapping;
+
+	if (udev->product) {
+		for(j = 0; xpad_flavor[j].idVendor; j++) {
+			if (!strcmp(udev->product, xpad_flavor[j].product)) {
+				xpad->mapping |= xpad_flavor[j].mapping;
+				break;
+			}
+		}
+	}
+
 	xpad->xtype = xpad_device[i].xtype;
 	xpad->name = xpad_device[i].name;
 	xpad->quirks = xpad_device[i].quirks;

@blindedone1458
Copy link
Contributor

As for your PR, I think it is good to have but just that the CapabilityMap doesn't need all those Mappings in it. Could have a basic mapping in it for the C and Z buttons since the Xbox Elite / Series controllers don't have a C or Z:

mapping:
  - name: C Button
    target_event:
      gamepad:
        button: LeftStick
    source_events:
      - gamepad:
          button: LeftPaddle3
  - name: Z Button
    target_event:
      gamepad:
        button: RightStick
    source_events:
      - gamepad:
          button: RightPaddle3

@pastaq
Copy link
Contributor

pastaq commented Mar 5, 2025

Can someone post a picture of the controller with all the buttons labeled for context?

@belozer
Copy link

belozer commented Mar 5, 2025

For the Share button, are you referring to the Circle button

@blindedone1458 Yes, that's correct. Circle is the FN button. I didn't think that data was also transmitted. But I saw
KEY_RECORD (BTN_TRIGGER_HAPPY11 in first version) in your patch.

I think we need to try mapping it to the "Share" button.

cc @pastaq

Apex 4
image

Vader 4
image

This is necessary for taking screenshots and full mapping of the Xbox Elite controller.
image

@belozer
Copy link

belozer commented Mar 5, 2025

Ohh... I forgot. The "Share" button only exists on the Xbox Series controller. On the Xbox Elite 2 controller, this button switches profiles. I have not used the controller in a long time...

But at the same time, when you look at the Steam interface you can see this button.

image

Xbox Series
image

Xbox Elite 2
image

But will cool mapping FN to it if possible.

@belozer
Copy link

belozer commented Mar 5, 2025

@blindedone1458 thanks! It works #308 (comment)

Now Steam recognizes FN as the Screenshot/Share button, tested on Flydigi Apex 4. Paddle Buttons also works and recognized in Steam (by using InputPlumber).

@belozer
Copy link

belozer commented Mar 6, 2025

@pastaq a gamepad with paddle button layout for context. I have marked it in orange.

Flydigi Vader 3/4 (Apex 4 the same)
image

@pastaq
Copy link
Contributor

pastaq commented Mar 6, 2025

Interesting.

Buttons C and Z are going to be a challenge as there isn't a normal function for them on modern controllers. They are part of the original dinput spec and produce valid codes (BTN_C/BTN_Z). The original Xbox controller has them as well as things like the sidewinder and the Sega Saturn controller. They have fallen out of favor since the 360 came out. It feels incorrect to map them to happy trigger. We also haven't fully decided what to do with them in InputPlumber as they fit into a weird spot where they aren't really a standard capability or button like abxy are, despite being an extension of that.

@belozer
Copy link

belozer commented Mar 10, 2025

It seems that these buttons (C, Z) need to be connected to keyboard events in the current situation.

E.g.

Home, End
Page Up, Page Down
Left Alt, Right Alt

@belozer
Copy link

belozer commented Mar 10, 2025

The current solution for Apex 4 meets 90% of the needs. The remaining 10% is the gyroscope.

Also ability to change at least the backlight color, but that's another story.

@italoghost
Copy link

italoghost commented Mar 16, 2025

Hi, everyone! I have a Vader 3 Pro and I wasn't able to make it work as an Elite Controller. I have already patched xpad with the patch provided on #308 (comment) and I can confirm that it is working with evtest. But after creating the two files from this PR (/usr/share/inputplumber/capability_maps/flydigi_type1.yaml and usr/share/inputplumber/devices/59-flydigi_vader_pro.yaml), my controller is still being recognized as a Xbox 360 controller.

Does anyone have any clue on how I can debug it or make it work? I have inputplumber installed through the ArchLinux package (not the AUR-bin one).

@pastaq
Copy link
Contributor

pastaq commented Mar 16, 2025

@italoghost when you run evtest there is some info it prints out at the beginning with things like the name of the device and it's vid/PID, enabled buttons, can you post that?

It should look something like this

#208 (comment)

If so, the vid/pid in the patch and the inputplumber config will need to be changed.

@pastaq
Copy link
Contributor

pastaq commented Mar 16, 2025

The current solution for Apex 4 meets 90% of the needs. The remaining 10% is the gyroscope.

Also ability to change at least the backlight color, but that's another story.

I wasn't aware this thing had gyro. Can you install hid-tools and use hid-recorder to find out if there is an hidraw device that has gyro data?

@belozer
Copy link

belozer commented Mar 16, 2025

The current solution for Apex 4 meets 90% of the needs. The remaining 10% is the gyroscope.
Also ability to change at least the backlight color, but that's another story.

I wasn't aware this thing had gyro. Can you install hid-tools and use hid-recorder to find out if there is an hidraw device that has gyro data?

X-Input

I forgot that when a gamepad is connected to a computer using XInput, it works at the firmware level. Depending on the settings, the gyroscope movements are mapped to the left or right stick.

I've now activated the gyro using official flydigi software and tested it on both Linux and Windows systems. Everything works as expected and similar.

The gamepad in XInput mode doesn't need any additional adjustments.

hid-record does not show anything in this mode.

D-Input (via dongle)

It looks like the gyroscope is defined as a mouse device when connected via D-Input.

hid-recorder result
# Flydigi Flydigi VADER3
# 0x05, 0x01,                    // Usage Page (Generic Desktop)        0
# 0x09, 0x02,                    // Usage (Mouse)                       2
# 0xa1, 0x01,                    // Collection (Application)            4
# 0x85, 0x02,                    //  Report ID (2)                      6
# 0x09, 0x01,                    //  Usage (Pointer)                    8
# 0xa1, 0x00,                    //  Collection (Physical)              10
# 0x05, 0x09,                    //   Usage Page (Button)               12
# 0x19, 0x01,                    //   Usage Minimum (1)                 14
# 0x29, 0x05,                    //   Usage Maximum (5)                 16
# 0x15, 0x00,                    //   Logical Minimum (0)               18
# 0x25, 0x01,                    //   Logical Maximum (1)               20
# 0x95, 0x05,                    //   Report Count (5)                  22
# 0x75, 0x01,                    //   Report Size (1)                   24
# 0x81, 0x02,                    //   Input (Data,Var,Abs)              26
# 0x95, 0x01,                    //   Report Count (1)                  28
# 0x75, 0x03,                    //   Report Size (3)                   30
# 0x81, 0x01,                    //   Input (Cnst,Arr,Abs)              32
# 0x05, 0x01,                    //   Usage Page (Generic Desktop)      34
# 0x09, 0x30,                    //   Usage (X)                         36
# 0x09, 0x31,                    //   Usage (Y)                         38
# 0x16, 0x01, 0xf8,              //   Logical Minimum (-2047)           40
# 0x26, 0xff, 0x07,              //   Logical Maximum (2047)            43
# 0x75, 0x0c,                    //   Report Size (12)                  46
# 0x95, 0x02,                    //   Report Count (2)                  48
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              50
# 0x09, 0x38,                    //   Usage (Wheel)                     52
# 0x15, 0x81,                    //   Logical Minimum (-127)            54
# 0x25, 0x7f,                    //   Logical Maximum (127)             56
# 0x75, 0x08,                    //   Report Size (8)                   58
# 0x95, 0x01,                    //   Report Count (1)                  60
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              62
# 0x95, 0x01,                    //   Report Count (1)                  64
# 0x81, 0x03,                    //   Input (Cnst,Var,Abs)              66
# 0xc0,                          //  End Collection                     68
# 0xc0,                          // End Collection                      69
# 
R: 70 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 05 15 00 25 01 95 05 75 01 81 02 95 01 75 03 81 01 05 01 09 30 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38 15 81 25 7f 75 08 95 01 81 06 95 01 81 03 c0 c0
N: Flydigi Flydigi VADER3
I: 3 04b4 2412

Additional records

@belozer
Copy link

belozer commented Mar 16, 2025

Hi, everyone! I have a Vader 3 Pro and I wasn't able to make it work as an Elite Controller. I have already patched xpad with the patch provided on #308 (comment) and I can confirm that it is working with evtest. But after creating the two files from this PR (/usr/share/inputplumber/capability_maps/flydigi_type1.yaml and usr/share/inputplumber/devices/59-flydigi_vader_pro.yaml), my controller is still being recognized as a Xbox 360 controller.

Does anyone have any clue on how I can debug it or make it work? I have inputplumber installed through the ArchLinux package (not the AUR-bin one).

It seems that the name field in the evdev section of the configuration is causing the mapping to break. I have tested this on Apex 4. We will need to find out what is causing this issue.

My current worked solution.

  1. Apply that patch for Xpad feat(Flydigi): Add support for flydigi vader 3/4 pro #308 (comment)
  2. Apply the InputPlumber configuration to the device.
  3. Restart InputPlumber sudo systemctl restart inputplumber

Sources:

/usr/share/inputplumber/devices/59-flydigi-vader.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/composite_device_v1.json
# Schema version number
version: 1

# The type of configuration schema
kind: CompositeDevice

# Name of the composite device mapping
name: flydigi-vader

# Only use this profile if *any* of the given matches matches. If this list is
# empty,then the source devices will *always* be checked.
# /sys/class/dmi/id/product_name
matches: []

# Only allow a single source device per composite device of this type.
single_source: true

# One or more source devices to combine into a single virtual device. The events
# from these devices will be watched and translated according to the key map.
source_devices:
  - group: gamepad
    unique: true
    evdev:
      vendor_id: "045e"
      product_id: "028e"
      handler: event*

# The target input device(s) that the virtual device profile can use
target_devices:
  - xbox-elite

options:
  auto_manage: true

NOTE: After patching the Xpad, you don't need to configure the capability_maps for button remapping because they already have the correct mapping set up.

@belozer
Copy link

belozer commented Mar 16, 2025

@italoghost when you run evtest there is some info it prints out at the beginning with things like the name of the device and it's vid/PID, enabled buttons, can you post that?

It should look something like this

#208 (comment)

If so, the vid/pid in the patch and the inputplumber config will need to be changed.

evtest (apex 4 via dongle)
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x45e product 0x28e version 0x104
Input device name: "Microsoft X-Box 360 pad"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 167 (KEY_RECORD)
    Event code 304 (BTN_SOUTH)
    Event code 305 (BTN_EAST)
    Event code 307 (BTN_NORTH)
    Event code 308 (BTN_WEST)
    Event code 310 (BTN_TL)
    Event code 311 (BTN_TR)
    Event code 314 (BTN_SELECT)
    Event code 315 (BTN_START)
    Event code 316 (BTN_MODE)
    Event code 317 (BTN_THUMBL)
    Event code 318 (BTN_THUMBR)
    Event code 708 (BTN_TRIGGER_HAPPY5)
    Event code 709 (BTN_TRIGGER_HAPPY6)
    Event code 710 (BTN_TRIGGER_HAPPY7)
    Event code 711 (BTN_TRIGGER_HAPPY8)
    Event code 712 (BTN_TRIGGER_HAPPY9)
    Event code 713 (BTN_TRIGGER_HAPPY10)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      7
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 1 (ABS_Y)
      Value     -7
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 2 (ABS_Z)
      Value      0
      Min        0
      Max      255
    Event code 3 (ABS_RX)
      Value    -22
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 4 (ABS_RY)
      Value     -7
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 5 (ABS_RZ)
      Value      0
      Min        0
      Max      255
    Event code 16 (ABS_HAT0X)
      Value      0
      Min       -1
      Max        1
    Event code 17 (ABS_HAT0Y)
      Value      0
      Min       -1
      Max        1
  Event type 21 (EV_FF)
    Event code 80 (FF_RUMBLE)
    Event code 81 (FF_PERIODIC)
    Event code 88 (FF_SQUARE)
    Event code 89 (FF_TRIANGLE)
    Event code 90 (FF_SINE)
    Event code 96 (FF_GAIN)
lsusb -v -d 045e:028e (apex 4 via dongle)
Bus 003 Device 025: ID 045e:028e Microsoft Corp. Xbox360 Controller
Couldn't open device, some information will be missing
Negotiated speed: Full Speed (12Mbps)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass       255 Vendor Specific Subclass
  bDeviceProtocol       255 Vendor Specific Protocol
  bMaxPacketSize0         8
  idVendor           0x045e Microsoft Corp.
  idProduct          0x028e Xbox360 Controller
  bcdDevice            1.04
  iManufacturer           1 Flydigi
  iProduct                2 Flydigi VADER3
  iSerial                 3 Flydigi VADER3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x008b
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93 [unknown]
      bInterfaceProtocol      1 
      iInterface              0 
      ** UNRECOGNIZED:  11 21 10 01 01 25 81 14 03 03 03 04 13 05 08 03 03
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93 [unknown]
      bInterfaceProtocol      3 
      iInterface              0 
      ** UNRECOGNIZED:  1b 21 00 01 01 01 82 40 01 06 20 16 85 00 00 00 00 00 00 16 05 00 00 00 00 00 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93 [unknown]
      bInterfaceProtocol      2 
      iInterface              0 
      ** UNRECOGNIZED:  09 21 00 01 01 22 86 07 00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval              16
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    253 [unknown]
      bInterfaceProtocol     19 
      iInterface              4 
      ** UNRECOGNIZED:  06 41 00 01 01 03

@italoghost
Copy link

Hi, everyone! I have a Vader 3 Pro and I wasn't able to make it work as an Elite Controller. I have already patched xpad with the patch provided on #308 (comment) and I can confirm that it is working with evtest. But after creating the two files from this PR (/usr/share/inputplumber/capability_maps/flydigi_type1.yaml and usr/share/inputplumber/devices/59-flydigi_vader_pro.yaml), my controller is still being recognized as a Xbox 360 controller.
Does anyone have any clue on how I can debug it or make it work? I have inputplumber installed through the ArchLinux package (not the AUR-bin one).

It seems that the name field in the evdev section of the configuration is causing the mapping to break. I have tested this on Apex 4. We will need to find out what is causing this issue.

My current worked solution.

1. Apply that patch for Xpad [feat(Flydigi): Add support for flydigi vader 3/4 pro #308 (comment)](https://github.com/ShadowBlip/InputPlumber/pull/308#issuecomment-2702019418)

2. Apply the InputPlumber configuration to the device.

3. Restart InputPlumber `sudo systemctl restart inputplumber`

Sources:
/usr/share/inputplumber/devices/59-flydigi-vader.yaml

# yaml-language-server: $schema=https://raw.githubusercontent.com/ShadowBlip/InputPlumber/main/rootfs/usr/share/inputplumber/schema/composite_device_v1.json
# Schema version number
version: 1

# The type of configuration schema
kind: CompositeDevice

# Name of the composite device mapping
name: flydigi-vader

# Only use this profile if *any* of the given matches matches. If this list is
# empty,then the source devices will *always* be checked.
# /sys/class/dmi/id/product_name
matches: []

# Only allow a single source device per composite device of this type.
single_source: true

# One or more source devices to combine into a single virtual device. The events
# from these devices will be watched and translated according to the key map.
source_devices:
  - group: gamepad
    unique: true
    evdev:
      vendor_id: "045e"
      product_id: "028e"
      handler: event*

# The target input device(s) that the virtual device profile can use
target_devices:
  - xbox-elite

options:
  auto_manage: true

NOTE: After patching the Xpad, you don't need to configure the capability_maps for button remapping because they already have the correct mapping set up.

Thanks, @belozer! After removing the capability_maps file and changing the 59-flydigi-vader.yaml to the one you provided, my controller was recognized as a Elite Controller!

Here is the output of evtest:

No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event3:	Microsoft X-Box One Elite 2 pad
Select the device event number [0-3]: 3
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x45e product 0xb00 version 0x1
Input device name: "Microsoft X-Box One Elite 2 pad"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 167 (KEY_RECORD)
    Event code 304 (BTN_SOUTH)
    Event code 305 (BTN_EAST)
    Event code 307 (BTN_NORTH)
    Event code 308 (BTN_WEST)
    Event code 310 (BTN_TL)
    Event code 311 (BTN_TR)
    Event code 314 (BTN_SELECT)
    Event code 315 (BTN_START)
    Event code 316 (BTN_MODE)
    Event code 317 (BTN_THUMBL)
    Event code 318 (BTN_THUMBR)
    Event code 704 (BTN_TRIGGER_HAPPY1)
    Event code 705 (BTN_TRIGGER_HAPPY2)
    Event code 706 (BTN_TRIGGER_HAPPY3)
    Event code 707 (BTN_TRIGGER_HAPPY4)
    Event code 708 (BTN_TRIGGER_HAPPY5)
    Event code 709 (BTN_TRIGGER_HAPPY6)
    Event code 710 (BTN_TRIGGER_HAPPY7)
    Event code 711 (BTN_TRIGGER_HAPPY8)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value     13
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
      Resolution       1
    Event code 1 (ABS_Y)
      Value     -8
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
      Resolution       1
    Event code 2 (ABS_Z)
      Value      0
      Min        0
      Max      255
      Resolution       1
    Event code 3 (ABS_RX)
      Value    -14
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
      Resolution       1
    Event code 4 (ABS_RY)
      Value    -14
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
      Resolution       1
    Event code 5 (ABS_RZ)
      Value      0
      Min        0
      Max      255
      Resolution       1
    Event code 16 (ABS_HAT0X)
      Value      0
      Min       -1
      Max        1
      Resolution       1
    Event code 17 (ABS_HAT0Y)
      Value      0
      Min       -1
      Max        1
      Resolution       1
  Event type 21 (EV_FF)
    Event code 80 (FF_RUMBLE)
    Event code 81 (FF_PERIODIC)
    Event code 88 (FF_SQUARE)
    Event code 89 (FF_TRIANGLE)
    Event code 90 (FF_SINE)
    Event code 96 (FF_GAIN)
Properties:
Testing ... (interrupt to exit)

@italoghost
Copy link

I also would like to report that the C and Z buttons have stopped working, as expected. If you need to test the gyro with my specific controller, I can help with the data/logs!

@belozer
Copy link

belozer commented Mar 16, 2025

@italoghost You ran the evtest after replacing the gamepad via the InputPlumber.

Could you please stop the InputPlumber.

sudo systemctl stop inputplumber

and retrieve the evtest report?

It would also be good to add the lsusb output result (I need to understand how it differs from Apex 4 and whether we can already somehow determine which is Apex and which is Vader)

lsusb -v -d 045e:028e

After that, you can run the InputPlumber again.

sudo systemctl start inputplumber

@italoghost
Copy link

Sure, @belozer! Here it is:

evtest output:

No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event2:	Microsoft X-Box 360 pad
Select the device event number [0-2]: 2
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x45e product 0x28e version 0x104
Input device name: "Microsoft X-Box 360 pad"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 167 (KEY_RECORD)
    Event code 304 (BTN_SOUTH)
    Event code 305 (BTN_EAST)
    Event code 307 (BTN_NORTH)
    Event code 308 (BTN_WEST)
    Event code 310 (BTN_TL)
    Event code 311 (BTN_TR)
    Event code 314 (BTN_SELECT)
    Event code 315 (BTN_START)
    Event code 316 (BTN_MODE)
    Event code 317 (BTN_THUMBL)
    Event code 318 (BTN_THUMBR)
    Event code 708 (BTN_TRIGGER_HAPPY5)
    Event code 709 (BTN_TRIGGER_HAPPY6)
    Event code 710 (BTN_TRIGGER_HAPPY7)
    Event code 711 (BTN_TRIGGER_HAPPY8)
    Event code 712 (BTN_TRIGGER_HAPPY9)
    Event code 713 (BTN_TRIGGER_HAPPY10)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      0
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 1 (ABS_Y)
      Value      0
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 2 (ABS_Z)
      Value      0
      Min        0
      Max      255
    Event code 3 (ABS_RX)
      Value     -6
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 4 (ABS_RY)
      Value     -7
      Min   -32768
      Max    32767
      Fuzz      16
      Flat     128
    Event code 5 (ABS_RZ)
      Value      0
      Min        0
      Max      255
    Event code 16 (ABS_HAT0X)
      Value      0
      Min       -1
      Max        1
    Event code 17 (ABS_HAT0Y)
      Value      0
      Min       -1
      Max        1
  Event type 21 (EV_FF)
    Event code 80 (FF_RUMBLE)
    Event code 81 (FF_PERIODIC)
    Event code 88 (FF_SQUARE)
    Event code 89 (FF_TRIANGLE)
    Event code 90 (FF_SINE)
    Event code 96 (FF_GAIN)
Properties:
Testing ... (interrupt to exit)

lsusb -v -d 045e:028e output:

Bus 003 Device 006: ID 045e:028e Microsoft Corp. Xbox360 Controller
Negotiated speed: Full Speed (12Mbps)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass       255 Vendor Specific Subclass
  bDeviceProtocol       255 Vendor Specific Protocol
  bMaxPacketSize0         8
  idVendor           0x045e Microsoft Corp.
  idProduct          0x028e Xbox360 Controller
  bcdDevice            1.04
  iManufacturer           1 Flydigi
  iProduct                2 Flydigi VADER3
  iSerial                 3 Flydigi VADER3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0031
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass     93 [unknown]
      bInterfaceProtocol      1
      iInterface              0
      ** UNRECOGNIZED:  11 21 00 01 01 25 81 14 00 00 00 00 13 05 08 03 03
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
Device Status:     0x0000
  (Bus Powered)

@italoghost
Copy link

Hi! Since the support for the Vader 4 Pro was added to the latest release, is the there any chances that this PR will be merged as well?

@pastaq
Copy link
Contributor

pastaq commented Apr 18, 2025

This needs to be updated to use a capability map v2 and ensure it matches the same capability translation that the hidraw version uses.

You can add an entry to the existing config for that instead of duplicating it, just add a comment to the entry that it's for xinput mode.

@italoghost
Copy link

italoghost commented Apr 18, 2025

This needs to be updated to use a capability map v2 and ensure it matches the same capability translation that the hidraw version uses.

You can add an entry to the existing config for that instead of duplicating it, just add a comment to the entry that it's for xinput mode.

Sorry, how do I do that? And by briefly looking at the commit c5f115f, the xpad patch could be dropped, right? I am using the Vader Pro 3, btw. Would it work for it as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flydigi Apex 4 support
5 participants