DirectInput API
DirectInput — это устаревший программный интерфейс (API) в составе Microsoft DirectX, предназначенный для обработки ввода с различных устройств, таких как джойстики, геймпады, рули, штурвалы, педали, а также клавиатуры и мыши. В отличие от стандартных механизмов ввода Windows (основанных на сообщениях), DirectInput обеспечивает прямой доступ к устройствам, минуя системную очередь сообщений, что позволяло добиться более низкой задержки и более точного опроса состояния кнопок и осей. API был впервые представлен в 1995 году в составе DirectX 1.0 и оставался основным способом работы с игровыми контроллерами в Windows до появления более современного API XInput. Начиная с DirectX 8, компания Microsoft официально рекомендовала разработчикам использовать DirectInput только для работы с устаревшими устройствами, а с DirectX 11 и 12 поддержка DirectInput была полностью прекращена в пользу XInput и более универсального Windows.Gaming.Input.
История
Появление и развитие
До появления DirectInput разработчикам игр для Windows приходилось полагаться на стандартный механизм сообщений Windows (WM_KEYDOWN, WM_KEYUP и т.д.) для обработки ввода с клавиатуры и мыши, а для работы с джойстиками — на устаревший API JoyGetPosEx. Эти методы имели ряд недостатков: задержки из-за буферизации сообщений, невозможность одновременного опроса нескольких осей джойстика с высокой частотой и отсутствие поддержки обратной связи (Force Feedback).
С выходом DirectX 1.0 в 1995 году DirectInput предоставил разработчикам прямой доступ к устройствам ввода, что позволило обойти системную очередь сообщений и получать данные с минимальной задержкой. API поддерживал буферизованный и немедленный режимы опроса, а также работу с устройствами обратной связи.
Расцвет и упадок
DirectInput активно использовался в играх конца 1990-х — начала 2000-х годов, особенно в симуляторах (авиасимуляторы, автосимуляторы) и аркадных играх, где требовалась поддержка сложных контроллеров с большим количеством осей и кнопок. Однако с появлением в 2005 году контроллера Xbox 360 и его стандартного драйвера для Windows компания Microsoft представила новый API — XInput. XInput был значительно проще в использовании, оптимизирован для работы с контроллерами Xbox и поддерживал вибрацию (Force Feedback) «из коробки».
Microsoft начала постепенно отказываться от DirectInput. Начиная с DirectX 8, API был объявлен устаревшим для клавиатуры и мыши, а с DirectX 11 и 12 поддержка DirectInput была полностью удалена из основного пакета DirectX SDK. Разработчикам рекомендовалось использовать XInput для всех современных контроллеров и Windows.Gaming.Input для универсальных приложений Windows (UWP). Несмотря на это, DirectInput остаётся единственным способом работы с некоторыми устаревшими игровыми устройствами (например, старыми джойстиками с интерфейсом MIDI/game port) и продолжает использоваться в некоторых эмуляторах и специализированных программах.
Архитектура и принцип работы
Основные компоненты
DirectInput состоит из нескольких ключевых интерфейсов COM (Component Object Model):
- IDirectInput8 — основной интерфейс, используемый для создания экземпляра DirectInput, перечисления доступных устройств и создания устройств.
- IDirectInputDevice8 — интерфейс для управления конкретным устройством (джойстиком, клавиатурой, мышью). Позволяет установить формат данных, задать режим кооперации (эксклюзивный или неэксклюзивный), активировать Force Feedback и опрашивать состояние устройства.
- IDirectInputEffect — интерфейс для управления эффектами обратной связи (Force Feedback). Позволяет создавать, запускать, останавливать и изменять параметры вибрации, ударов и других тактильных ощущений.
Режимы ввода
DirectInput поддерживает два основных режима опроса устройств:
- Немедленный режим (Immediate Data) — приложение вызывает метод
GetDeviceState, который возвращает текущее состояние всех кнопок и осей устройства в виде структуры данных (например,DIJOYSTATE2для джойстика). Этот режим прост в реализации, но может приводить к потере данных, если приложение не успевает опрашивать устройство достаточно часто. - Буферизованный режим (Buffered Data) — приложение вызывает метод
GetDeviceData, который возвращает массив событий (нажатие кнопки, изменение оси) с метками времени. Этот режим позволяет гарантированно обработать каждое событие, но требует больше памяти и сложнее в реализации.
Формат данных
Для каждого устройства разработчик должен задать формат данных с помощью макроса DIMOUSESTATE2 (для мыши), DIKEYBOARDSTATE (для клавиатуры) или DIJOYSTATE2 (для джойстика). Формат определяет, какие оси и кнопки будут опрашиваться и в каком порядке они будут расположены в структуре данных. Для джойстиков DIJOYSTATE2 поддерживает до 6 осей (X, Y, Z, Rx, Ry, Rz), 128 кнопок, 4 POV-шляпки (point-of-view hat) и 4 слайдера.
Кооперативный уровень
DirectInput позволяет задать уровень кооперации (cooperative level) для устройства, который определяет, как устройство будет взаимодействовать с другими приложениями и системой:
- DISCL_NONEXCLUSIVE — приложение не требует монопольного доступа к устройству. Другие приложения также могут получать данные с этого устройства.
- DISCL_EXCLUSIVE — приложение требует монопольного доступа. Другие приложения не смогут получить данные с устройства, пока оно не будет освобождено.
- DISCL_FOREGROUND — приложение получает данные только когда находится на переднем плане (активное окно).
- DISCL_BACKGROUND — приложение может получать данные даже когда находится в фоне.
Поддерживаемые устройства
Клавиатура и мышь
DirectInput может работать с клавиатурой и мышью, позволяя опрашивать их состояние напрямую. Однако начиная с DirectX 8, Microsoft рекомендовала использовать для этих устройств стандартный механизм сообщений Windows, так как DirectInput не поддерживает некоторые функции (например, обработку мультимедийных клавиш, распознавание раскладки клавиатуры, работу с колесом прокрутки мыши в некоторых конфигурациях).
Джойстики, геймпады и рули
Основная область применения DirectInput — работа с игровыми контроллерами. API поддерживает устройства с произвольным количеством осей, кнопок, POV-шляпок и слайдеров. Для каждого устройства можно задать диапазон значений осей (минимальное и максимальное значение), мёртвую зону (dead zone) и насыщение (saturation).
Устройства Force Feedback
DirectInput предоставляет интерфейсы для управления устройствами обратной связи (Force Feedback), такими как джойстики с вибрацией, рули с эффектом сопротивления и игровые кресла с тактильной отдачей. API поддерживает создание различных эффектов:
- Постоянный эффект (Constant Force) — постоянное усилие, прикладываемое к оси.
- Периодический эффект (Periodic Force) — колебательное усилие (синусоида, пила, треугольник, квадрат).
- Эффект рампа (Ramp Force) — усилие, линейно нарастающее или убывающее со временем.
- Удар (Condition) — усилие, зависящее от текущего состояния оси (например, пружина, демпфер, трение).
Сравнение с XInput
| Параметр | DirectInput | XInput | |
|---|---|---|---|
| Год появления | 1995 (DirectX 1.0) | 2005 (DirectX 9.0c) | |
| Поддержка контроллеров | Любые устройства (джойстики, рули, геймпады, клавиатура, мышь) | Только контроллеры Xbox 360, Xbox One, Xbox Series X\ | S |
| Количество осей | До 6 осей + 4 слайдера | До 4 осей (левый/правый стик, триггеры) | |
| Количество кнопок | До 128 кнопок | До 10 кнопок + 2 триггера | |
| Force Feedback | Поддерживается через отдельные интерфейсы | Встроенная поддержка вибрации (два мотора) | |
| Сложность использования | Высокая (требуется ручная настройка формата данных, кооперативного уровня, буферизации) | Низкая (простой вызов функций для получения состояния) | |
| Поддержка в современных версиях Windows | Отсутствует (DirectX 11/12) | Полная поддержка | |
| Использование | Устаревшие игры, эмуляторы, специализированное ПО | Современные игры, приложения UWP |
Критика и ограничения
Устаревшая архитектура
DirectInput был разработан в середине 1990-х годов и не учитывает многие современные требования: поддержка сенсорных экранов, акселерометров, гироскопов, контроллеров движения (Nintendo Wii, PlayStation Move, Steam Controller). API не предоставляет средств для работы с батареей устройства, его уникальным идентификатором или возможностью обновления прошивки.
Сложность и избыточность
Для простых задач (например, опрос геймпада) DirectInput требует значительного количества кода: создание объекта DirectInput, перечисление устройств, создание устройства, установка формата данных, задание кооперативного уровня, опрос состояния. XInput решает ту же задачу тремя вызовами функций.
Отсутствие поддержки в новых версиях DirectX
Начиная с DirectX 11, DirectInput был удалён из основного пакета SDK. Разработчикам, желающим использовать DirectInput в современных приложениях, приходится либо использовать устаревший DirectX SDK (который больше не обновляется), либо подключать библиотеку DirectInput из состава DirectX End-User Runtime, который также считается устаревшим.
Проблемы с многопоточностью
DirectInput не является потокобезопасным. Разработчики должны синхронизировать доступ к объектам DirectInput из разных потоков вручную, что усложняет разработку многопоточных игр.
Применение в настоящее время
Несмотря на официальный отказ от поддержки, DirectInput продолжает использоваться в ряде областей:
- Эмуляторы старых игровых систем (MAME, Dolphin, PCSX2) — для поддержки большого количества устаревших контроллеров (джойстики с game port, MIDI-джойстики).
- Профессиональные симуляторы (Microsoft Flight Simulator X, Prepar3D, X-Plane) — для работы со сложными контроллерами (рули, педали, штурвалы) с большим количеством осей.
- Специализированное оборудование — некоторые промышленные контроллеры, медицинские джойстики и устройства ввода для людей с ограниченными возможностями всё ещё используют DirectInput.
- Пользовательские моды и патчи — для старых игр, которые не поддерживают XInput, существуют моды, эмулирующие DirectInput поверх XInput (например, x360ce).
Интересные факты
- DirectInput был одним из первых API, который поддерживал Force Feedback на персональных компьютерах. Первым устройством, использующим эту технологию, стал джойстик Microsoft SideWinder Force Feedback Pro (1997 год).
- В DirectInput существует возможность создания «виртуальных устройств» — программных эмуляторов джойстиков, которые могут быть использованы для тестирования или автоматизации.
- Некоторые игры, выпущенные после 2010 года, всё ещё поддерживают DirectInput для совместимости с устаревшими контроллерами, но при этом используют XInput для современных геймпадов (например, серия игр Grand Theft Auto V).
- В составе DirectX SDK до версии 9.0c входил инструмент
DInputCfg.exe, позволявший настраивать параметры джойстика (калибровка осей, мёртвая зона) для приложений, использующих DirectInput.
Источники
- Microsoft DirectX SDK Documentation (DirectInput section), 1995–2010.
- «DirectX 9.0c: Programming Guide» by Microsoft Corporation, 2005.
- «Game Programming Gems» (серия книг), разделы по обработке ввода.
- «Windows Game Programming with DirectX» by André LaMothe, 1998.
- Документация Microsoft по XInput и Windows.Gaming.Input, 2005–2024.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →