DirectInput手柄Windows环境下震动实现

  • 背景
  • 1.direcrInput手柄震动控制
    • 1.1运行环境
    • 1.2代码实现
  • 2 模拟XInput设备,通过XInput实现
    • 2.1 x360ce设置
  • 2.2 XInput 代码实现
    • 2.3 x360ce分析

背景

近期项目里面有个需求,需要在控制终端上安装摇杆,且需要通过震动反馈设备的某些重要运行状态。自以为机智的自己在万能的某宝买了一个飞行摇杆,带震动反馈,DInput接口,结果是踩坑的开始。
Windows下手柄分为两类,XInput和DirectInput,XInput主要是Xbox系列手柄,比较贵,亲儿子;市面上大多杂牌的手柄都只支持DirectInput。查阅官方文档:xinput and directinput 心凉了半截:The vibration effects will not be available,意思就是directinput不再支持手柄震动了。不过directInput有一个directInputEffect,从文档看是力反馈,论坛说也能拿来做震动,因此先用directInput做一下尝试。

1.direcrInput手柄震动控制

1.1运行环境

环境搭建就不再赘述,主要就是选一个win10的tool kit,已经集成了directx。Qt是项目中用于界面搭建的环境。
(1)windows 10 1903
(2)Qt 5.9

1.2代码实现

github 上有比较完整的 QGameController,能够实现手柄的识别、各参数的读取,封装比较完整,但是没有手柄震动的驱动。本着不重复造轮子的原则,从这个开源项目开始进行代码实现。

    DWORD dwAxisX = DIJOFS_X;  //一个震动电机LONG lDirecX = 0;DIPERIODIC diPeriodic;      ZeroMemory(&diPeriodic, sizeof(DIPERIODIC));DICONSTANTFORCE diConstantForce;ZeroMemory(&diConstantForce, sizeof(DICONSTANTFORCE));DIEFFECT   diEffect;        // general parameters// set up the effect structure itselfdiEffect.dwSize = sizeof(DIEFFECT);diEffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;diEffect.dwDuration = (DWORD) INFINITE; diEffect.dwStartDelay = 0;// set up details of effectdiEffect.dwSamplePeriod = 0;               diEffect.dwGain = lVibraStrength;      diEffect.dwTriggerButton = DIEB_NOTRIGGER;// connect effect to trigger buttondiEffect.dwTriggerRepeatInterval = 0;diEffect.cAxes = 1;diEffect.rgdwAxes = &dwAxisX;diEffect.rglDirection = &lDirecX;diEffect.lpEnvelope = 0;diConstantForce.lMagnitude = DI_FFNOMINALMAX;diEffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);diEffect.lpvTypeSpecificParams = &diConstantForce;// create the effect and get the interface to ithr = g_pJoystick->CreateEffect(GUID_ConstantForce,  // standard GUID&diEffect,      // where the data is&lpdieffect,    // where to put interface pointerNULL);          // no aggregationif(FAILED(hr)){qDebug()<< "create effect failed";}g_pJoystick->SendForceFeedbackCommand(DISFFC_RESET);//g_pJoystick->SendForceFeedbackCommand(DISFFC_SETACTUATORSON);if( FAILED(g_pJoystick->SendForceFeedbackCommand(DISFFC_SETACTUATORSON)))qDebug() << "start failed";hr = lpdieffect->Download();if(FAILED(hr))qDebug("download failed, the error NO is %X",hr);hr = lpdieffect->Start(INFINITE,DIES_SOLO);if(FAILED(hr))qDebug("start failed, the error NO is %X",hr);

代码有些冗长,参照了策随心和code从业员两位大佬的一些参数设置,虽然用的语言不一样,但是道理都是一样的。
代码运行并没有那么顺利,手柄在download和start以后,并没有反应,整个世界都是清净的。查找错误代码是0x80040205 DIERR_NOTEXCLUSIVEACQUIRED,注释是:The operation cannot be performed unless the device is acquired in DISCL_EXCLUSIVE mode。意思是这个操作在独占模式下才可以实现。因此我在create前面加了:

    if( FAILED(hr = g_pJoystick->SetCooperativeLevel(windID,DISCL_BACKGROUND|DISCL_EXCLUSIVE)))qDebug("error set coopreative, error NO is %X",hr);

运行,世界还是一片寂静。这个bug直到现在都没调好,有大佬知道为啥,请告诉我!

2 模拟XInput设备,通过XInput实现

deadline越来越近,不能在一条路上撞死。逛论坛找大神的时候,发现DInput的设备可以通过软件模拟,变成XInput设备。在微软提供的XInput库中,有函数直接可以实现vibration。尝试了多个软件以后,找到了开源的x360ce,程序和源代码都能在官网上找到。

2.1 x360ce设置

在完成相关设置后,可以一键autosetting。上面一排标签可以看到Force Feedback,在这个选项卡中,拖动test的进度条后,手柄震动起来了,第一步完成。

2.2 XInput 代码实现

在qt中搭一个简单界面,按键做震动开关。把下面的代码块放到按键的槽函数中。

    XINPUT_VIBRATION vibration;ZeroMemory( &vibration, sizeof(XINPUT_VIBRATION) );vibration.wLeftMotorSpeed = LeftMotorSpeed; vibration.wRightMotorSpeed = RightMotorSpeed; XInputSetState( uID, &vibration );

把x360ce中生成的xinput1_3.dll放到程序的运行目录下面,点击运行,动了!果然是亲儿子,这么小的代码量就能解决上面一片的所有问题。

2.3 x360ce分析

看了一下开源的代码,这个软件主要分为两大部分,一部分是生成dll文件,C++;一部分是界面,C#。
x360ce_dll工程里,代码量不大,主要是通过DirectInput控制手柄,再给XInput提供接口。震动的实时是调用XInputSetState,而不是directInputEffect.start,所以没有出现上面的独占问题。

DirectInput手柄在Windows环境下震动实现相关推荐

  1. resin-pro-4.0.34 服務器在windows环境下的配置

    resin-pro-4.0.34 服務器在windows环境下的配置 (轉載请注明作者:icelong) 到caucho網站上http://www.caucho.com/download/ 下載 re ...

  2. Windows环境下Unicode编程总结和将ANSI转换到Unicode 将Unicode转换到ANSI

    Windows环境下Unicode编程总结 UNICODE环境设置 在安装Visual Studio时,在选择VC++时需要加入unicode选项,保证相关的库文件可以拷贝到system32下. UN ...

  3. mysql8.0卸载出现问题,Windows环境下MySQL 8.0 的安装、配置与卸载

    软件版本 Windows:Windows10 MySQL:mysql-8.0.17-winx64.zip 安装步骤 1.配置环境变量 2.新建my.ini文件 文件位置:C:\Program File ...

  4. php-cgi和php-fpm,Windows环境下解决Nginx+php并发访问阻塞问题。

    php-cgi 是运行php, php-fpm是守护php-cgi进程 nginx配置目录运行php         location  ~ \.php$         {              ...

  5. Redis学习笔记~Redis在windows环境下的安装

    Redis是一个key-value的存储系统,它最大的特点就是可以将数据序列化到文件中. redis存储在服务器的内存或者文件中,它不是session,不是cookies,它只是个更安全,更稳定,更可 ...

  6. Windows环境下在IDEA编辑器中spark开发安装步骤

    以下是windows环境下安装spark的过程: 1.安装JDK(version:1.8.0.152) 2.安装scala(version:2.11/2.12) 3.安装spark(version:s ...

  7. windows环境下搭建rabbitMQ开发环境

    2019独角兽企业重金招聘Python工程师标准>>> windows环境下搭建rabbitMQ开发环境 1.下载与安装 erlang rabbitmq 是使用erlang语言开发的 ...

  8. 在Windows环境下搭建Android开发环境

    标题:在Windows环境下搭建 Android 开发环境 作者:CrazyPebble 时间:2011年2月28日 声明:此文在参考其他网上资料以及笔者实践总结写下,一来自己可以做一些总结,二来给跟 ...

  9. 腾讯云CMQ消息队列在Windows环境下的使用

    版权声明:本文由李少华原创文章,转载请注明出处:  文章原文链接:https://www.qcloud.com/community/article/100 来源:腾云阁 https://www.qcl ...

  10. MemCache在Windows环境下的搭建及启动

    MemCache在Windows环境下的搭建及启动 一.memcache服务器端的安装 1.下载memcached的安装包,memcached_en32or64.zip,下载链接:http://pan ...

最新文章

  1. 重磅!基金委发布科研不端行为调查处理办法
  2. struts2的配置文件
  3. HDU 2041 超级楼梯
  4. 线上操作与线上问题排查实战
  5. 如何异步的处理restful服务(基础)
  6. Android SqliteManager 源码
  7. 大道至简伪代码(第一个博客)
  8. 谈谈JAVA工程狮面试中经常遇到的面试题目------什么是MVC设计模式
  9. C++程序设计(第2版)课后习题答案--第11章
  10. 全国计算机水平考试技巧,全国计算机等级考试上机考试应试技巧
  11. 部署web应用程序到tomcat
  12. java删除表操作,JDBC删除表实例
  13. centos安装python3.8与pip
  14. 【OpenCV学习笔记】【错误处理】计算机缺失MSVCP120D.dll
  15. Vue 引入 zepto
  16. 几种常用的键盘钩子技术
  17. 计算机局域网地址设置方法,怎么设置局域网电脑的ip地址和DNS?
  18. 2022年金三银四你应该去面试跳槽吗?
  19. nginx配置错误导致的目录穿越漏洞
  20. 机器人与视觉,基于TCP(工具坐标)偏移

热门文章

  1. 博图os更新_PCS7和TIA博图软件有什么区别?
  2. 数论入门基础(同余定理/费马小定理/扩展欧几里德算法/中国剩余定理)~
  3. [VGG16]——网络结构介绍及搭建(PyTorch)
  4. matlab均值滤波实现
  5. 视频教程-2020软考数据库系统工程师-基础知识培训视频-软考
  6. 【OpenCv3】 VS C++ (五):SLIC超像素分割算法
  7. c语言队列的作用,C语言队列
  8. LaTeX 语法教程
  9. 计算机视觉专业名词中英文对照(转)
  10. CF probabilities 自制题单