Вопрос или проблема
Я хочу иметь возможность перехватывать событие FF (силовая отдача) (вибрация/дрожание в данном случае), которое обычно направляется напрямую в файл устройства игрового контроллера, чтобы отправить событие на какое-то другое устройство, при этом оставив игровой контроллер конечным получателем события. Это в надежде создать нативную для Linux альтернативу инструменту, доступному только для Windows, под названием Intiface Game Haptics Router (недопустимый случай использования, делает в основном то, что написано на упаковке)
Я уже пытался безуспешно создать скрипт на Python с использованием python-evdev
, чтобы читать события, идущие к игровому контроллеру, но оказывается, что события UInput не содержат информацию о длине или интенсивности, если вы не начинаете загружать их на устройство, и мне не удалось захватить событие с реального игрового контроллера и загрузить его на виртуальный с теми же “возможностями” FF (я предполагаю, что приложение все еще напрямую общается с игровым контроллером, поэтому виртуальное устройство ничего не получает?). Возможно, это нехватка опыта с библиотекой, так как я в основном собрал вместе несколько примерных скриптов из раздела с учебными материалами на сайте документации
В предыдущей попытке сделать что-то подобное я наткнулся на xboxdrv
, драйвер пользовательского пространства для игровых контроллеров Xbox. У него, похоже, есть некоторый функционал для отправки FF-событий на определенное устройство из-за некоторых крайних случаев. К сожалению, это не полезно, потому что эта опция имеет ограниченное применение, не позволяя указывать файлы устройств.
Я видел, что могу использовать модуль ядра usbmon
и wireshark для перехвата USB-сообщений, однако я считаю, что это немного громоздко для настройки (как программно, так и вручную, я хотел бы, чтобы удобство использования учитывалось, поскольку слышал, что даже некоторые пользователи Steam Deck пытались использовать инструмент для Windows). У меня также есть опасения по поводу производительности и задержки, так как некоторые игры могут сильно нагружать систему, и если два устройства будут слишком сильно рассинхронизированы, это может сбивать с толку.
Для справки, я немного любитель Linux, я в основном использую Arch Linux и его производные на протяжении нескольких лет, в основном с KDE Plasma. Что касается кода, упомянутого ранее, я мог бы поделиться фрагментом кода, который пытался сделать работающим, но, как я уже говорил, он собран из примеров, так что там нет ничего революционного.
Я понимаю, что это странное нишевое дело и трудная задача, поэтому заранее большое спасибо, если вы сможете хотя бы осветить мой путь. И извините, если это не тот форум, я немного нов в Stack Exchange и имел некоторые трудности с тем, чтобы определить, к какому именно из них подходит мой вопрос.
Ответ или решение
Перехват событий обратной связи (Force Feedback): Руководство для Linux
Введение
Перехват событий обратной связи от игровых контроллеров в Linux — это непростая задача, особенно если вы хотите отправить эти события на другое устройство, сохранив при этом функциональность оригинального контроллера. В данном руководстве мы рассмотрим возможности реализации такого решения, используя существующие инструменты и библиотеки на Linux.
Проблема и её сущность
Как вы справедливо заметили, одно из основных препятствий в вашей задаче — это отсутствие необходимых данных о силе и продолжительности вибрации в событиях, отправленных через UInput
. Это связано с тем, что оригинальная игра отправляет команды непосредственно на устройство, минуя ваш виртуальный контроллер. Использование python-evdev
также может оказаться ограниченным, особенно если вы не до конца понимаете, как правильно использовать его функционал для обработки событий обратной связи.
Возможные решения
-
Использование
uinput
иevdev
для создания виртуального контроллераВы можете попробовать создать виртуальный контроллер с помощью
uinput
и объединить его с обработкой событий с оригинального контроллера. Примерный план:- Создайте виртуальное устройство, используя
UInput
. - Подписывайтесь на события, отправляемые вашему контроллеру, через
evdev
. - Когда событие обратной связи осуществляется, вы получаете информацию о его интенсивности и длительности.
- Повторно отправьте это событие как на оригинальный контроллер, так и на ваше виртуальное устройство.
Пример кода:
import evdev from evdev import InputDevice, UInput, ecodes as ev # Открытие устройства игры gamepad = InputDevice('/dev/input/eventX') # замените на ваш путь устройства ui = UInput() for event in gamepad.read(): if event.type == ev.EV_FF: # Обработка события обратной связи ui.write(ev.EV_FF, event.code, event.value) # Отправляем на виртуальный контроллер gamepad.write(ev.EV_FF, event.code, event.value) # Отправляем на оригинальный контроллер ui.syn() gamepad.syn()
- Создайте виртуальное устройство, используя
-
Использование
usbmon
и анализа USB-трафикаХотя вы считаете использование
usbmon
громоздким, это один из самых мощных способов решения вашей задачи. Пакеты могут быть захвачены с использованиемwireshark
, а затем повторно отправлены в реальном времени, обеспечивая высокую точность и контроль над параметрами обратной связи.Вы можете автоматизировать данный процесс, написав скрипт, который будет захватывать нужные события и отправлять их на ваше либо любое другое устройство.
-
Пользовательские драйвера
Если вы чувствуете себя уверенно в написании модулей для ядра Linux, можете рассмотреть создание собственного драйвера, который будет перехватывать события перед их отправкой в устройство. Это обеспечит вам полное управление данными о вибрации и способности отправки их на другое устройство.
Оптимизация производительности
Для снижения задержек и повышения производительности ото всех сценариев:
- Рассмотрите возможность использования реального программного обеспечения для сбора и обработки событий в режиме реального времени.
- Убедитесь, что ваш код оптимизирован для минимизации нагрузок на CPU.
- Сведите к минимуму задержки вызова метода через использование асинхронного программирования, например, с помощью библиотеки
asyncio
.
Заключение
Создание системы для перехвата событий обратной связи от игрового контроллера на Linux — это сложная, но выполнимая задача. С помощью вышеописанных методов и подходов вы можете достичь своей цели. Не забывайте документировать ваш процесс и делиться базовым кодом с сообществом — это поможет не только вам, но и другим, кто пытается решить аналогичную задачу. Удачи в ваших усилиях!