finn163 Posted January 3, 2015 Share Posted January 3, 2015 (edited) Доброго времени суток, друзья. Нужна ваща помощь. Товарищи Kharlashkin, inj3ct0r и sirmax сделали мод позволяющий использовать вибрации с официальной вибронакидки, передавая их на Геймпад. С этим вы можете ознакомится здесь 'Ссылка на офф форум раз' http://forum.worldoftanks.ru/index.php?/topic/1196499-%D0%B8%D0%B3%D1%80%D0%B0%D0%B5%D0%BC-%D0%B2-world-of-tanks-%D0%BD%D0%B0-%D0%B3%D0%B5%D0%B9%D0%BC%D0%BF%D0%B0%D0%B4%D0%B5 и здесь 'Ссылка на офф форум два' http://forum.worldoftanks.ru/index.php?/topic/1480568-%D0%B8%D0%B3%D1%80%D0%B0%D0%B5%D0%BC-%D0%B2-world-of-tanks-%D0%BD%D0%B0-%D0%B3%D0%B5%D0%B9%D0%BC%D0%BF%D0%B0%D0%B4%D0%B5-%D0%BF%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5/ Проблем при использовании геймпадов с поддержкой XInput (стандарт данных для геймпадов XBOX 360) не наблюдается, но вот геймпад с использованием DirectInput никак не реагируют на вибрацию. Мне собственно нужно сделать так, что бы мы могли завести вибрацию на геймпадах без поддержки XInput (тобишь на обычных с поддержкой DirectInput) Для подключения накидки используется следующий алгоритм. 'Алгоритм подключения накидки' 1. Необходимо установить Python версий 2.7.х (у меня стоит 2.7.6).2. Необходимо установить Flask, я делал по этой инструкции. Качаем файл distribute_setup.py в папку "C:\temp" (например), запускаем консоль "Win+R" - cmd и выполняем команду "C:\Python27\python.exe C:\temp\distribute_setup.py" наблюдаем процесс загрузки нужных файлов в папку "C:\Python27\Scripts", далее в консоли запускаем команды по очереди и наблюдаем их выполнение:C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py FlaskC:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Jinja2C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py WerkzeugC:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py Virtualenv3. Распаковать мод в нужную папку. 'Ссылка на мод' https://drive.google.com/file/d/0B7WlhvVxLC1DcUZtaktSc3V5REk/edit После этого Танки говорят что видят вибронакидку, и передают команды о вибрациях на геймпад. Проблема в том что поскольку у DirectInput другой алгоритм, он эти сигналы совершенно не воспринимает. И даже в Эмуляторах x360 и x360 vibromod, геймпад не вибрирует, по той же причине. В папке с модом который лежит у нас в директории модов world of tanks есть файлик на питоне, который по словам kharlashkin-а отправляют сигналы на геймпад о вибрации. Декомпилировав имеем код 'Код' # Embedded file name: .\gpXInput.pyimport ctypesclass XINPUT_VIBRATION(ctypes.Structure):_fields_ = [('wLeftMotorSpeed', ctypes.c_ushort), ('wRightMotorSpeed', ctypes.c_ushort)]class gpXInputClass:def __init__(self):xInputDLLFileName = 'xinput1_3'xinput = ctypes.WinDLL(xInputDLLFileName)self.__XInputSetState = xinput.XInputSetStateself.__XInputSetState.argtypes = [ctypes.c_uint, ctypes.POINTER(XINPUT_VIBRATION)]self.__XInputSetState.restype = ctypes.c_uintself.__l = 0self.__r = 0def adjust_vibration(self, left_motor_delta, right_motor_delta, set = False, controller = 0):if set:self.__l = left_motorself.__r = right_motorelse:self.__l += left_motor_deltaself.__r += right_motor_deltatempL = self.__ltempR = self.__rif self.__l > 255:tempL = 255elif self.__l < 0:tempL = 0if self.__r > 255:tempR = 255elif self.__r < 0:tempR = 0vibration = XINPUT_VIBRATION(int(tempL * 65535 / 255), int(tempR * 65535 / 255))self.__XInputSetState(controller, ctypes.byref(vibration))def stop_vibration(self, controller = 0):vibration = XINPUT_VIBRATION(0, 0)self.__XInputSetState(controller, ctypes.byref(vibration))gpXInputObject = gpXInputClass() Сам в програмировании на таком уровне не очень секу, так что очень нужна помощь. Как я понимаю достаточно переписать этот код так, что бы он отправлял сигналы воспринимаемые DirectInput-ом, тобишь все сигналы переделать. Про DirectInput нашел на майкрософтовском сайте, но сам толком ничего не разобрал. Вот ссыль 'Ссылка DirectInput Force Feedback' http://msdn.microsoft.com/en-us/library/windows/desktop/ee417563(v=vs.85).aspx Уж очень нужна помощь. Просто нужно переделать из одного стандарта (XInput) в другой (DirectInput). Программисты помогите! Edited January 3, 2015 by finn163 1 @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 3, 2015 Share Posted January 3, 2015 Я изучал данную тему, мое мнение не нужно переводить Xinput вибрации в Directinput, проще будет изменить модуль вывода вибраций из мода сразу для Directinput. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 4, 2015 Share Posted January 4, 2015 (edited) Итак, делюсь своими наработками и новыми вводными данными. 1. Гугление привело к тому что нужно наверное использовать SDL - наверное самый простой способ для меня, так как переделать код из C++ для python не смогу. 2. Нашел тестовый скрипт для проверки вибраций. 'testhaptic.py' """Simple example for haptic/force-feedback""" import os import sys import ctypes import sdl2 def run(): sdl2.SDL_Init(sdl2.SDL_INIT_TIMER | sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_HAPTIC) print "Trying to find haptics" if (sdl2.SDL_NumHaptics() == 0): print "No haptic devices found" sdl2.SDL_Quit() exit(0) for index in range(0,sdl2.SDL_NumHaptics()): print "Found", index, ":", sdl2.SDL_HapticName(index) if (len(sys.argv) == 2): index = int(sys.argv[1]) else: index = 0 haptic = sdl2.SDL_HapticOpen(index); if haptic == None: print "Unable to open device" sdl2.SDL_Quit() exit(0) else: print "Using device", index nefx = 0 efx = [0] * 12 id = [0] * 12 supported = sdl2.SDL_HapticQuery(haptic) if (supported & sdl2.SDL_HAPTIC_SINE): print " effect", nefx, "Sine Wave" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_SINE, periodic= \ sdl2.SDL_HapticPeriodic(type=sdl2.SDL_HAPTIC_SINE, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_POLAR, dir=(9000,0,0)), \ period=1000, magnitude=0x4000, length=5000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_TRIANGLE): print " effect", nefx, "Triangle" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_TRIANGLE, periodic= \ sdl2.SDL_HapticPeriodic(type=sdl2.SDL_HAPTIC_SINE, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_CARTESIAN, dir=(1,0,0)), \ period=1000, magnitude=0x4000, length=5000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_SAWTOOTHUP): print " effect", nefx, "Sawtooth Up" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_SAWTOOTHUP, periodic= \ sdl2.SDL_HapticPeriodic(type=sdl2.SDL_HAPTIC_SAWTOOTHUP, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_POLAR, dir=(9000,0,0)), \ period=500, magnitude=0x5000, length=5000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_SAWTOOTHDOWN): print " effect", nefx, "Sawtooth Down" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_SAWTOOTHDOWN, periodic= \ sdl2.SDL_HapticPeriodic(type=sdl2.SDL_HAPTIC_SAWTOOTHDOWN, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_CARTESIAN, dir=(1,0,0)), \ period=500, magnitude=0x5000, length=5000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_RAMP): print " effect", nefx, "Ramp" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_RAMP, ramp= \ sdl2.SDL_HapticRamp(type=sdl2.SDL_HAPTIC_RAMP, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_POLAR, dir=(9000,0,0)), \ start=0x5000, end=0x0000, length=5000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_CONSTANT): print " effect", nefx, "Constant Force" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_CONSTANT, constant= \ sdl2.SDL_HapticConstant(type=sdl2.SDL_HAPTIC_CONSTANT, direction=sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_CARTESIAN, dir=(1,0,0)), \ length=5000, level=0x4000, attack_length=1000, fade_length=1000)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_SPRING): print " effect", nefx, "Spring" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_SPRING, condition= \ sdl2.SDL_HapticCondition(type=sdl2.SDL_HAPTIC_SPRING, length=5000, right_sat=(0x7FFF,0x7FFF,0x7FFF), left_sat=(0x7FFF,0x7FFF,0x7FFF), \ right_coeff=(0x2000,0x2000,0x2000), left_coeff=(0x2000,0x2000,0x2000), center=(0x1000,0x1000,0x1000))) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_DAMPER): print " effect", nefx, "Damper" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_DAMPER, condition= \ sdl2.SDL_HapticCondition(type=sdl2.SDL_HAPTIC_DAMPER, length=5000, right_sat=(0x7FFF,0x7FFF,0x7FFF), left_sat=(0x7FFF,0x7FFF,0x7FFF), \ right_coeff=(0x2000,0x2000,0x2000), left_coeff=(0x2000,0x2000,0x2000), center=(0x1000,0x1000,0x1000))) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_INERTIA): print " effect", nefx, "Interia" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_INERTIA, condition= \ sdl2.SDL_HapticCondition(type=sdl2.SDL_HAPTIC_INERTIA, length=5000, right_sat=(0x7FFF,0x7FFF,0x7FFF), left_sat=(0x7FFF,0x7FFF,0x7FFF), \ right_coeff=(0x2000,0x2000,0x2000), left_coeff=(0x2000,0x2000,0x2000), center=(0x1000,0x1000,0x1000))) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_FRICTION): print " effect", nefx, "Friction" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_FRICTION, condition= \ sdl2.SDL_HapticCondition(type=sdl2.SDL_HAPTIC_FRICTION, length=5000, right_sat=(0x7FFF,0x7FFF,0x7FFF), left_sat=(0x7FFF,0x7FFF,0x7FFF), \ right_coeff=(0x2000,0x2000,0x2000), left_coeff=(0x2000,0x2000,0x2000), center=(0x1000,0x1000,0x1000))) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 if (supported & sdl2.SDL_HAPTIC_LEFTRIGHT): # leftright argument not defined for HapticEffect print " effect", nefx, "Left/Right" print " Bug 'leftright' not defined" efx[nefx] = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_LEFTRIGHT, leftright= \ sdl2.SDL_HapticLeftRight(type=sdl2.SDL_HAPTIC_LEFTRIGHT, length=5000, large_magnitude=0x3000, small_magnitude=0xFFFF)) id[nefx] = sdl2.SDL_HapticNewEffect(haptic, efx[nefx]); nefx += 1 print "Now playing effects for 5 seconds each with 1 second delay between" for i in range(0, nefx): print " Playing effect", i sdl2.SDL_HapticRunEffect(haptic, id[i], 1); sdl2.SDL_Delay(6000); # Effects only have length 5000 sdl2.SDL_Quit() return 0 if __name__ == "__main__": sys.exit(run()) 3. Сам PySDL2 взял отсюда - https://bitbucket.org/marcusva/py-sdl2 4. Установил по этой инструкции http://pysdl2.readthedocs.org/en/latest/install.html#installation. 5. Вываливается ошибка: Не могу понять куда подсовывать SDL.dll. Может подскажет кто? Добавил путь к SDL.dll в переменную среду. Теперь ошибка следующая: Traceback (most recent call last): File "C:\temp\testhaptic.py", line 5, in <module> import sdl2 File "D:\Python27\lib\site-packages\sdl2\__init__.py", line 2, in <module> from .dll import get_dll_file, _bind File "D:\Python27\lib\site-packages\sdl2\dll.py", line 113, in <module> raise ImportError(exc) ImportError: found ['D:\\SDL2\\SDL2.dll'], but it's not usable for the library SDL2 "УРА! Заработало!" ©кот Матроскин: Теперь подробнее автору топика про установку и проверку. 1. Установить Python (у меня установлено 2.7.8), хотя мне кажется уже установлено. 2. Качаем отсюда py-sdl2 версию PySDL2-0.9.3.zip. 3. Распаковываем тупо на диск "С:\" 4. Из консоли Windows ("Win+R" - cmd) переходим в распакованную папку - "cd c:\pysdl2-0.9.3". 5. Выполняем установку - "c:\python27\python.exe setup.py install" 6. Качаем c libsdl.org архив для 32-х битной Windows - SDL2-2.0.3-win32-x86.zip. 7. Распаковываем файл SDL.dll в папку "C:\SDL2". 8. Добавляем папку "C:\SDL2" в переменные среды (Компьютер - Свойства - Дополнительные параметры системы - Переменные среды - Создать) 9. Качаем тестовый скрипт и кладем его куда угодно (у меня "C:\temp"). 10. Открываем его в IDLE. 11. Клавишей F5 запускаем проверку. Если завибрирует - хорошо, если нет - то ХЗ. Edited January 4, 2015 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
finn163 Posted January 4, 2015 Author Share Posted January 4, 2015 (edited) Итак, оказывается Xpadder конфликтует с x360 эмулятором и тот отказывается вибрировать. Без Хпадера х360 работает на ура. Как и х360 Vibromod. Несмотря на то что удалось запустить вибрацию в режиме XInput в программе х360, в танках работать вибрация отказывается. При любых заменах XInputa в дириктории питона и даже винде, всё одно - не работает в танках. Тобишь просто так на эмуляторе идет вибрации, а при попытке выхватить её из Питона не работает. Тем неменее на обычных геймпадах с XInput-ом всё ок, выхватывает из питона как надо. Диагноз - х360 не перехватывает сигнал и не преобразует его в DirectInput, а на геймпад идут обычные сигналы в XInput-е, а он их естественно не воспринимает. Так что по прежнему нужна помощь программистов:) Edited January 4, 2015 by finn163 @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 4, 2015 Share Posted January 4, 2015 Конкретно у автора темы тестовая вибрация SDL не завелась - хотя эффекты и пытались проиграться: Скорее всего, мне кажется что это бока программистов из SpeedLink, а может и разработчиков SDL (на оф.форуме есть жалобы на работу вибраций Directinput). Вспомнился мой пост о мытарствах подключения геампада под python, вспомнился проект PsychoPy и нашелся нужный код, который вроде без промежуточных DLL умеет обращаться с геймпадами. http://pydoc.net/Python/PsychoPy/1.81.03/psychopy.hardware.joystick.pyglet_input.dinput/ http://pydoc.net/Python/PsychoPy/1.81.03/psychopy.hardware.joystick.pyglet_input.directinput/ Если я правильно понимаю, нужно выбросить все лишнее и можно использовать это для вызова напрямую вибраций? @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 5, 2015 Share Posted January 5, 2015 (edited) На форуме поддержки x360ce, накопал интересную информацию касательно эмуляции геймпада Xbox 360. Документ использования перехватов прилагаю. Как оказалось, что в стандартный графический интерфейс (как это обычно и бывает) не внесены все возможности использования, полностью все возможности доступны в файле настройки, а именно x360ce.ini. [InputHook] HookLL=0 HookCOM=0 HookSA=0 HookWT=0 HookDI=0 HookPIDVID=0 HookName=0 Так как мы вызываем вибрации непосредственно из xinput1_3.dll - мне кажется что именно HookLL тот параметр, в который нужно поставить 1. P.S. Ну вообще рекомендую более глубоко покопаться в документации. Может найдутся ещё скрытые возможности. Если ничего не поможет - попробуйте попросить помощи у них на форуме. P.P.S. Вот кстати и список игр, для которых нужны отличные от стандартных настройки, для некоторых нужны несколько параметров hook-ов. Проверил какой именно exe-шник обращается к xinput1_3.dll при работе мода, по этой инструкции: Нужно автору темы пробовать играться с параметрами: HookLL=(0/1) HookCOM=(0/1) HookSA=(0/1) HookWT=(0/1) HOOKDI=(0/1) HOOKPIDVID=(0/1) HookName=(0/1) Сгенерированную DLL положить в папку с системным python "C:\Python27". Вспомнил про тестовый скрипт. Чтобы не запускать танки постоянно, просто запустить в редакторе ff.py. Тестовый скрипт запускает левый мотор на максимум и правый в пол силы в течении 5 секунд. x360ce_intro_to_input_hooking2.pdf ff.7z Edited January 5, 2015 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 6, 2015 Share Posted January 6, 2015 Ни у кого нет геймпадов или никто не хочет помочь - проверить? Интересно что скрипт проверочный скачали 3 раза - документ с хуками ни разу... P.S. Вчера вечером проверил на своих геймпадах - SDL вывалил ошибку, типа не назначены коэфициенты для левого/правого моторов (глубоко не копал), проверочный скрипт работает как положено. @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted January 7, 2015 Share Posted January 7, 2015 Проверил - python действительно обращается к xinput1_3.dll x360ce, при размещении файлов в папке "C:\Python27\". Но так как DirectInput геймпада нет у меня - дальше проверки дело не идет. @ Quote Link to comment Short link Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.