原文链接:https://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx

XInput是一个允许应用从Windows平台Xbox 360控制器中接收输入的API。该文档描述XInput和DirectInput关于Xbox 360控制器接口间的不同,并说明如何在同一时间同时支持XInput设备和传统DirectInput设备。
 
注意:传统DirectInput目前不推荐使用,并且在Windows Store里面的应用已经不支持DirectInput。
 
新的标准:XInput
XInput目前可以应用于游戏开发,这个新的输入标准可以应用于Xbox 360、Windows XP SP1及以上版本以及Windows Vista。该APIs在DirectX SDK中包含,并且通过Windows Update可以更新驱动。
 
XInput相较于DirectInput有以下方面的优势:
  • XInput比DirectInput更方便使用并且创建步骤更少
  • Xbox 360和Windows编程使用相同的核心APIs集,并且跨平台编程更方便
  • Xbox 360有一个非常大的用户群
  • XInput设备(也就是指Xbox 360控制器)将在仅使用XInput APIs时具备震动功能
  • 未来发布关于Xbox 360操纵台的控制器(也就是方向盘)将同样可以应用于Windows
 
将DirectInput应用于Xbox 360控制器
Xbox 360可以通过DirectInput进行枚举,并且可以应用DirectInput APIs。然而,某些XInput提供的功能在DirectInput中不存在:
  • 左、右扳柄不作为独立的单一按钮
  • 震动效果不可用
  • 无法查询头戴式设备
在DirectInput中设计左右扳柄处于组合状态,游戏常常假定当没有用户与设备交互时DirectInput设备轴处于中间。然而,Xbox 360控制器设计该位置为最小值,并不是中间,当触发器没有被控制时,老的游戏因此假定用户处于交互状态。
 
解决方案是配置扳柄,设置一个为负向和另一个为正向,所以当没有用户交互时表示DirectInput控制处于中间状态。
 
为了分别测试扳柄的值,此时必须用XInput。
 
同时支持XInput和DirectInput
假如仅仅支持XInput,游戏将不能工作在传统的DirectInput设备上。XInput将不会识别这些设备。
 
如何想让游戏支持传统DirectInput设备,需要同时使用DirectInput和XInput。当枚举DirectInput设备时,所有DirectInput设备将枚举成功。所有的XInput设备将同时显示在XInput和DirectInput设备中,但是他们不应该通过DirectInput处理。你需要决定那些DirectInput设备是传统设备,那些是XInput设备并且从DirectInput设备枚举集里面将他们移除。
 
为实现这个目的,将下面这些代码插入到DirectInput回调函数里面:
#include <wbemidl.h>
#include <oleauto.h>
#include <wmsstd.h> //-----------------------------------------------------------------------------
// Enum each PNP device using WMI and check each device ID to see if it contains
// "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
// Unfortunately this information can not be found by just using DirectInput
//-----------------------------------------------------------------------------
BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
{
IWbemLocator* pIWbemLocator = NULL;
IEnumWbemClassObject* pEnumDevices = NULL;
IWbemClassObject* pDevices[] = {};
IWbemServices* pIWbemServices = NULL;
BSTR bstrNamespace = NULL;
BSTR bstrDeviceID = NULL;
BSTR bstrClassName = NULL;
DWORD uReturned = ;
bool bIsXinputDevice= false;
UINT iDevice = ;
VARIANT var;
HRESULT hr; // CoInit if needed
hr = CoInitialize(NULL);
bool bCleanupCOM = SUCCEEDED(hr); // Create WMI
hr = CoCreateInstance( __uuidof(WbemLocator),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IWbemLocator),
(LPVOID*) &pIWbemLocator);
if( FAILED(hr) || pIWbemLocator == NULL )
goto LCleanup; bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; // Connect to WMI
hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L,
0L, NULL, NULL, &pIWbemServices );
if( FAILED(hr) || pIWbemServices == NULL )
goto LCleanup; // Switch security level to IMPERSONATE.
CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); hr = pIWbemServices->CreateInstanceEnum( bstrClassName, , NULL, &pEnumDevices );
if( FAILED(hr) || pEnumDevices == NULL )
goto LCleanup; // Loop over all devices
for( ;; )
{
// Get 20 at a time
hr = pEnumDevices->Next( , , pDevices, &uReturned );
if( FAILED(hr) )
goto LCleanup;
if( uReturned == )
break; for( iDevice=; iDevice<uReturned; iDevice++ )
{
// For each device, get its device ID
hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL );
if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device
// This information can not be found from DirectInput
if( wcsstr( var.bstrVal, L"IG_" ) )
{
// If it does, then get the VID/PID from var.bstrVal
DWORD dwPid = , dwVid = ;
WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != )
dwVid = ;
WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != )
dwPid = ; // Compare the VID/PID to the DInput device
DWORD dwVidPid = MAKELONG( dwVid, dwPid );
if( dwVidPid == pGuidProductFromDirectInput->Data1 )
{
bIsXinputDevice = true;
goto LCleanup;
}
}
}
SAFE_RELEASE( pDevices[iDevice] );
}
} LCleanup:
if(bstrNamespace)
SysFreeString(bstrNamespace);
if(bstrDeviceID)
SysFreeString(bstrDeviceID);
if(bstrClassName)
SysFreeString(bstrClassName);
for( iDevice=; iDevice<; iDevice++ )
SAFE_RELEASE( pDevices[iDevice] );
SAFE_RELEASE( pEnumDevices );
SAFE_RELEASE( pIWbemLocator );
SAFE_RELEASE( pIWbemServices ); if( bCleanupCOM )
CoUninitialize(); return bIsXinputDevice;
} //-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
HRESULT hr; if( IsXInputDevice( &pdidInstance->guidProduct ) )
return DIENUM_CONTINUE; // Device is verified not XInput, so add it to the list of DInput devices return DIENUM_CONTINUE;
}

XInput和DirectInput的更多相关文章

  1. 如何通过XInput技术针对游戏方向盘或者手柄编程

    目前市面上的游戏外设,要么支持传统的DirectInput接口,要么支持最新的XInput技术.今天在这里聊一聊,如何通过XInput技术实现对这类游戏外设相关信息的捕获.关于DirectInput与 ...

  2. 创建DirectInput接口对象说明---(void **)&m_pDI

    读别人代码时遇到的,起初没明白过来这是怎么回事,后来忽然想明白了. if (FAILED(DirectInput8Create(appInstance, DIRECTINPUT_VERSION, II ...

  3. DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D

           本文从哈利_创.转载请注明出处.有问题欢迎联系本人!        邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...

  4. vux的x-input的源码分析

    <template> <div class="vux-x-input weui-cell" :class="{'weui-cell_warn': sho ...

  5. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记7——DirectInput&纹理映射

    第15章 DirectInput接口 DirectInput作为DirectX的组件之一,依然是一些COM对象的集合.DirectInput由IDirectinput8.IDirectInputDev ...

  6. Ubuntu通过xinput禁用及启用联想笔记本的触摸板

    查看设备列表 通过xinput先查看一些都有哪些设备 xinput     #或者 xinput list 显示结果如下 ddd@ddd:~$ xinput list   Virtual core p ...

  7. 如何通过DirectInput技术针对莱仕达雷驰V3II游戏方向盘编程

    三自由度的动感座椅可以让玩游戏人员在玩的过程中随座椅一起晃动,通过应用程序对方向盘动作的抓取来实现体感,动作类型主要分为加速(后仰,对应踩油门).减速(前倾,对应踩刹车 ).左转(向左打方向盘).右转 ...

  8. firefox浏览器中使用vux的x-input报错TypeError: _this3.$refs.input.scrollIntoViewIfNeeded is not a function

    最近做公众号项目,想着统一风格,所以决定使用vux. 在调试时发现,只要鼠标点击x-input输入框,就会报错 TypeError: _this3.$refs.input.scrollIntoView ...

  9. 使用vux的x-input组件中show-clear=“true”清除icon点击失效的问题

    问题场景: 在电脑浏览器点击清除icon正常 在手机浏览器,手机微信,微信开发者工具中点击清除icon失效 查看vux中的x-input组件中的源码发现,清除icon使用了v-show显示与隐藏,对应 ...

随机推荐

  1. 统计web应用程序的访问人数

    新建一个空网站,添加Global.asax全局处理. 文件目录如图: 在global类中添加代码: using System; using System.Collections.Generic; us ...

  2. 《Algorithms Unlocked》读书笔记1——循环和递归

    <Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础. 书中没有涉及编程语言,直接用文字描述算法,我用 J ...

  3. js 模板引擎

    template = document.querySelector('#template').innerHTML, result = document.querySelector('.result') ...

  4. Java 基础知识总结 2

    11.Java常用类: StringBuffer StringBuffer 是使用缓冲区的,本身也是操作字符串的,但是与String类不同,String类的内容一旦声明之后则不可以改变,改变的只是其内 ...

  5. Angular.js学习笔记 (二)

    用A链接对象解析url的组成 var url = 'https://www.baidu.com:8080/aaa/1.html?id=10#name'; var aLink = document.cr ...

  6. 跟着刚哥梳理java知识点——变量之间的类型转换(四)

    变量之间的类型转换主要包括自动类型转换和强制类型转换. 1.自动类型转换:当容量小的数据类型与容量大的数据类型做运算时,容量小的会自动的转换成容量大的类型. [知识点]: a)char,byte,sh ...

  7. loopj.com android-async-http

    loopj.com android-async-http Android异步Http客户端 用于Android的基于回调的Http客户端库   下载版本1.4.9(最新) 或者在github上fork ...

  8. 【模板】Tarjan求强连通分量

    有人说这篇博客不是很友好,所以我加了点解释,感觉是不是友好多了? dfn[u]表示节点u在dfs时被访问的次序. low[u]表示节点u能够追溯到的最远的祖先的dfn. ins[u]表示节点u是否在栈 ...

  9. iptables配置详解

    iptables主要参数 -A 向规则链中添加一条规则,默认被添加到末尾 -T指定要操作的表,默认是filter -D从规则链中删除规则,可以指定序号或者匹配的规则来删除 -R进行规则替换 -I插入一 ...

  10. linux网口绑定笔记-bind

    模式0:balance-rr 模式1:active-backup 模式2:balance-xor 模式3:broadcast 模式4:802.3ad 模式5:balance-tlb 模式6:balan ...