Elite Games - Свобода среди звезд!

Уроки для программистов - Устройства управления, ч.3

УСТРОЙСТВА УПРАВЛЕНИЯ
ЧАСТЬ ТРЕТЬЯ
DIRECTINPUT, ЧТО ЭТО ТАКОЕ И КАК ОНО РАБОТАЕТ

Раз вы читаете эту статью, значит рассматриваемая тема, вам интересна. И вы долго ждали, когда же, наконец, сможет вплотную приступить к программированию клавиатур, мышей и джойстиков. Время пришло, сейчас я расскажу вам, что такое DirectInput и как при помощи него узнать какие устройства управления у нас имеются в наличии.

DirectInput -- это составная часть DirectX, которая отвечает за устройства управления. DirectInput это ООП API, это значит, что нам придётся оперировать объектами, и хочу заметить их довольно много.

Так как же начать работать с DirectInput:
1. Создать объект DirectX.
2. Из объекта DirectX получить объект DirectInput (в нашем случае DirectInput8).
3. Из объекта DirectInput получить объект DirectInputEnumDevices.
4. В объекте DirectInputEnumDevices перечислены все устройства управления имеющиеся на компьютере и из него нам надо извлечь идентификаторы нужных устройств.
5. При помощи идентификаторов устройств создать нужное количество объектов DirectInputDevice.
6. Удалить из памяти объект DirectInputEnumDevices.
7. Для каждого из объектов DirectInputDevice получить описания утройства(количество осей, кнопок, “хаток”)
8. Установить каждому устройству нужный режим совместной работы, и тип принимаемых им данных.
9. Захватить устройство.
10. Получить данные из него(неограниченное число раз).
11. После того как устройство стало не надо, освободить его.
12. Удалить из памяти объекты DirectInputDevice, DirectInput, DirectX.

Как видите работы довольно много, но пугаться не стоит, мы будем делать всё по частям. Дальше я покажу, как это делается на VB6, на C++ и Delphi, это будет выглядеть почти также.

Private DX8 As New DirectX8 ’Объявляем и создаём объект DirecX8
Private DInput8 As DirectInput8 ’Объявляем, но не создаём объект DirectInput8
Private DID As DirectInputDevice8 ’ Тоже но для объекта DirectInputDevice8

Private Sub Form_Load()
DEVENUM As DirectInputEnumDevices8, X As Integer, STRp As Integer, STPp As Integer, A$, Y As Integer, ML As Integer, B$ ’Куча переменных включая объявленный объект DerectInputEnumDevice8
Set DInput8 = DX8.DirectInputCreate() ’ Из объекта DirectX создаём объект DirectInput8
Set DEVENUM = DInput8.GetDIDevices(DI8DEVCLASS_ALL, DIEDFL_ATTACHEDONLY) ’ Из объекта DirectInput8 получаем объект DirectInputEnumDevice8
GDev.Clear ’GDev таблица на форме она нам, не важна
GDev.Rows = 1
GDev.FormatString = «ProductName|InstanceName|ProductGUID|InstateGuid|ForceFeedBackGUID|DeviceType|HIDs Usage|HIDs UsagePage»

For X = 1 To DEVENUM.GetCount’ Получаем количество устройств запускаем цикл перебора всех устройств
GDev.AddItem DEVENUM.GetItem(X).GetProductName & vbTab & DEVENUM.GetItem(X).GetInstanceName _
& vbTab & DEVENUM.GetItem(X).GetGuidProduct & vbTab & DEVENUM.GetItem(X).GetGuidInstance _
& vbTab & DEVENUM.GetItem(X).GetGuidFFDriver & vbTab & DEVENUM.GetItem(X).GetDevType _
& vbTab & DEVENUM.GetItem(X).GetUsage & vbTab & DEVENUM.GetItem(X).GetUsagePage

GDev.Row = X ’Заносим в таблицу все возможные параметры, которые предоставляет на объект DirectInputEnumDevice8
Next X

Вырезано цензурой, так как оффтопик

’ Удаляем объекты из памяти в обратном порядке их зависимости друг от друга
Set DEVENUM = Nothing
Set DInput8 = Nothing
Set DX8 = Nothing
End Sub

Вот что мы имеем на выходе:



Теперь вопросы которые могут возникнуть:
Итак функция GetDIDevices принимает два параметра, первый тип устройства(CONST_DI8DEVICETYPE), второй флаги(CONST_DIENUMDEVICESFLAGS).
CONST_DI8DEVICETYPE -- содержит, довольно много констант, которые позволяют выбрать устройства выбирать как по классам:
DI8DEVCLASS_ALL -- все устройства
DI8DEVCLASS_DEVICE -- все устройства, которые не попадают ни под один из остальных классов
DI8DEVCLASS_POINTER -- все указательные устройства: мыши, трекболы, световые перья, сенсорные панели
DI8DEVCLASS_KEYBOARD -- Клавиатура
DI8DEVCLASS_GAMECTRL -- все игровые устройства: джойстики, геймпады, рули итд.

Так и по типу:
DI8DEVTYPE_DEVICE -- все устройства, которые не попадают ни под один из остальных типов
DI8DEVTYPE_MOUSE -- Мышь
DI8DEVTYPE_KEYBOARD -- Клавиатура
DI8DEVTYPE_JOYSTICK -- Джойстик
DI8DEVTYPE_GAMEPAD -- Геймпады
DI8DEVTYPE_DRIVING -- Рули
DI8DEVTYPE_FLIGHT -- Устройства для паллетов
DI8DEVTYPE_1STPERSON -- Устройства для шутеров(ума не приложу, что это возможно шлемы ВР с трекером)
DI8DEVTYPE_DEVICECTRL -- Устройства управления по принципу работы отличающиеся от всего остального
DI8DEVTYPE_SCREENPOINTER -- Не понял, что это такое возможно световое перо, или планшет
DI8DEVTYPE_REMOTE -- Устройства удалённого контроля(возможно имеются ввиду пульты ДУ)
DI8DEVTYPE_SUPPLEMENTAL -- Устройства помощники для других устройств, например педали для руля.

CONST_DIENUMDEVICESFLAGS -- содержи константы, которые позволяют выбрать устройства более точно:
DIEDFL_ALLDEVICES -- Все устройства
DIEDFL_ATTACHEDONLY -- Только подключённые устройства
DIEDFL_FORCEFEEDBACK -- Только устройства с функцией обратной связи
DIEDFL_INCLUDEALIASES -- Включая устройства псевдонимы
DIEDFL_INCLUDEHIDDEN -- Включая скрытые устройства
DIEDFL_INCLUDEPHANTOMS -- Включая устройства фантомы(не знаю, что такое)

Константы можно складывать вместе например GetDIDevices(DI8DEVCLASS_POINTER or DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY) вернёт список всех устройств относящихся к классам DI8DEVCLASS_POINTER и DI8DEVCLASS_GAMECTRL.

Теперь посмотрим, что же мы получили, а на выходе мы получаем объект, DirectInputEnumDevices из которого имеет две процедуры GetCount и GetItem. GetCount возвращает количество устройств. GetItem(index As Long) возвращает объект DirectInputDeviceInstance8 в котором содержит функции позволяющие получить описание устройства:
GetDevType -- тип устройства типы описаны константами CONST_DI8DEVICESUBTYPE(их очень много, поэтому расшифровывать не буду, кому интересно думаю сам найдёт)
GetGuidFFDriver -- Уникальный идентификатор(GUID) для работы с обратной связью.
GetGuidInstance -- Уникальный идентификатор устройства(все устройства системы имеют разные идентификаторы)
GetGuidProduct -- Уникальный идентификатор продукта, идентификатор который уникален для каждого устройства, но именно устройства, то есть два одинаковых джойстика будут иметь разные GuidInstance, но при этом одинаковые GuidProduct.
GetInstanceName -- Имя устройства в системе
GetProductName -- Имя устройства обычно совпадает с InstanceName
GetUsage -- внятного описания не нашёл
GetUsagePage -- внятного описания не нашёл

Из всех этих данных самые важные это GuidInstance и GuidFFDriver, так как при помощи них происходит работа с устройствами.
В следующей части мы научимся выяснять боле полную информацию о выбранном устройстве.

Пример к статье: http://www.elite-games.ru/downloads/art/program/devenum.rar
VBKesha
К началу раздела | Наверх страницы Сообщить об ошибке
Уроки для программистов - Устройства управления, ч.3
Все документы раздела: Для тех, кто хочет писать игры | Движок на OpenGL | Создание игр в Game Maker | Bump mapping | Использование Direct Input | XNA framework |


Дизайн Elite Games V5 beta.18
EGM Elite Games Manager v5.17 02.05.2010