Windows 应用程序中的 XInput 入门 您所在的位置:网站首页 windows游戏控制器 Windows 应用程序中的 XInput 入门

Windows 应用程序中的 XInput 入门

2023-08-10 03:51| 来源: 网络整理| 查看: 265

Windows 应用程序中的 XInput 入门 项目 06/13/2023

XInput 使 Windows 应用程序能够处理 Xbox 控制器交互 (包括控制器隆隆声效果以及语音输入和输出) 。

本主题简要概述了 XInput 的功能以及如何在应用程序中设置它。 包括以下各项:

XInput 简介 Xbox 控制器 使用 XInput 多个控制器 获取控制器状态 死区 设置振动效果 获取音频设备标识符 仅) (旧版 DirectX SDK 获取 DirectSound GUID 相关主题 XInput 简介

Xbox 主机使用与 Windows 兼容的游戏控制器。 应用程序在插入 Windows 电脑时可以使用 XInput API 与这些控制器通信 () 一次最多可以插入四个唯一控制器。

使用此 API,可以查询任何连接的 Xbox 控制器的状态,并且可以设置振动效果。 还可以查询附加了耳机的控制器,以获取可与头戴显示设备一起使用进行语音处理的声音输入和输出设备。

Xbox 控制器

Xbox 控制器有两个模拟方向摇杆,每个摇杆都有一个数字按钮、两个模拟触发器、一个具有四个方向的数字方向键和八个数字按钮。 调用 XInputGetState 函数时,将在 XINPUT_GAMEPAD 结构中返回每个输入的状态。

控制器还具有两个振动马达,用于向用户提供力回馈效果。 这些电机的速度在传递给 XInputSetState 函数以设置振动效果的 XINPUT_VIBRATION 结构中指定。

(可选)头戴显示设备可以连接到控制器。 头戴显示设备具有用于语音输入的麦克风和用于声音输出的耳机。 可以调用 XInputGetAudioDeviceIds 或旧版 XInputGetDSoundAudioDeviceGuids 函数来获取与麦克风和耳机设备对应的设备标识符。 然后,可以使用 核心音频 API 接收语音输入并发送声音输出。

使用 XInput

使用 XInput 就像根据需要调用 XInput 函数一样简单。 使用 XInput 函数,可以检索控制器状态、获取耳机音频 ID 以及设置控制器隆隆声效果。

多个控制器

XInput API 支持随时连接最多四个控制器。 XInput 函数都需要传入的 dwUserIndex 参数来标识要设置或查询的控制器。 此 ID 的范围为 0-3,由 XInput 自动设置。 该编号对应于控制器插入的端口,不可修改。

每个控制器通过在控制器中心的“光环”上点亮一个象限来显示它正在使用的 ID。 dwUserIndex 值 0 对应于左上角象限;编号按顺时针顺序围绕环进行。

应用程序应支持多个控制器。

获取控制器状态

在应用程序的整个过程中,可能最常从控制器获取状态。 在游戏应用程序中,应逐帧检索状态并更新游戏信息以反映控制器更改。

若要检索状态,请使用 XInputGetState 函数:

DWORD dwResult; for (DWORD i=0; i< XUSER_MAX_COUNT; i++ ) { XINPUT_STATE state; ZeroMemory( &state, sizeof(XINPUT_STATE) ); // Simply get the state of the controller from XInput. dwResult = XInputGetState( i, &state ); if( dwResult == ERROR_SUCCESS ) { // Controller is connected } else { // Controller is not connected } }

请注意, XInputGetState 的返回值可用于确定控制器是否已连接。 应用程序应定义一个结构来保存内部控制器信息;应将此信息与 XInputGetState 的结果进行比较,以确定该帧进行了哪些更改,例如按钮按下或模拟控制器增量。 在上面的示例中, g_Controllers 表示此类 结构。

在XINPUT_STATE结构中检索状态后,可以检查它进行更改,并获取有关控制器状态的特定信息。

XINPUT_STATE 结构的 dwPacketNumber 成员可用于检查控制器的状态是否自上次调用 XInputGetState 以来已更改。 如果 dwPacketNumber 在对 XInputGetState 的两次连续调用之间没有更改,则状态没有变化。 如果不同,则应用程序应检查XINPUT_STATE结构的 Gamepad 成员以获取更详细的状态信息。

出于性能原因,不要对每帧的“空”用户槽调用 XInputGetState 。 建议每隔几秒钟检查一次新控制器。

死区

为了让用户获得一致的游戏体验,你的游戏必须正确实现死区。 死区是控制器报告的“移动”值,即使模拟操纵杆未触及且居中也是如此。 2 个模拟触发器还有一个死区。

注意

使用完全不筛选死区 XInput 的游戏将体验糟糕的玩游戏。 请注意,某些控制器比其他控制器更敏感,因此死区可能因单元而异。 建议在不同的系统上使用多个 Xbox 控制器测试游戏。

应用程序应在模拟输入 (触发器、摇杆) 上使用“死区”,以指示何时在摇杆或触发器上进行了充分移动以被视为有效。

应用程序应检查死区并做出响应,如以下示例所示:

XINPUT_STATE state = g_Controllers[i].state; float LX = state.Gamepad.sThumbLX; float LY = state.Gamepad.sThumbLY; //determine how far the controller is pushed float magnitude = sqrt(LX*LX + LY*LY); //determine the direction the controller is pushed float normalizedLX = LX / magnitude; float normalizedLY = LY / magnitude; float normalizedMagnitude = 0; //check if the controller is outside a circular dead zone if (magnitude > INPUT_DEADZONE) { //clip the magnitude at its expected maximum value if (magnitude > 32767) magnitude = 32767; //adjust magnitude relative to the end of the dead zone magnitude -= INPUT_DEADZONE; //optionally normalize the magnitude with respect to its expected range //giving a magnitude value of 0.0 to 1.0 normalizedMagnitude = magnitude / (32767 - INPUT_DEADZONE); } else //if the controller is in the deadzone zero out the magnitude { magnitude = 0.0; normalizedMagnitude = 0.0; } //repeat for right thumb stick

此示例计算控制器的方向向量以及控制器已沿矢量推的距离。 这允许通过简单地检查控制器的量级是否大于死区值来强制实施循环死区。 此外,代码规范化控制器的量级,然后可以乘以游戏特定因子,将控制器的位置转换为与游戏相关的单位。

请注意,可以在 0-65534) (任意位置为摇杆和触发器定义自己的死区,也可以使用 XInput.h 中定义为XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE、XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE和XINPUT_GAMEPAD_TRIGGER_THRESHOLD的死区:

#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 #define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 #define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30

强制实施死区后,你可能会发现将生成的浮点范围 [0.0..1.0] 缩放为 ((如上面的) 示例中所示)并选择性地应用非线性转换很有用。

例如,对于驾驶游戏,将结果立方体来提供更好的使用游戏板驾驶汽车的感觉可能会有所帮助,因为将结果转换为更精确的较低范围,这是可取的,因为玩家通常要么应用软力来获得细微的运动,要么在一个方向上一直应用硬力以获得 rd 响应。

设置振动效果

除了获取控制器的状态外,还可以将振动数据发送到控制器,以更改提供给控制器用户的反馈。 控制器包含两个隆隆电机,可通过将值传递给 XInputSetState 函数来独立控制这些马达。

可以使用传递到 XInputSetState 函数的 XINPUT_VIBRATION 结构中的 WORD 值指定每个马达的速度,如下所示:

XINPUT_VIBRATION vibration; ZeroMemory( &vibration, sizeof(XINPUT_VIBRATION) ); vibration.wLeftMotorSpeed = 32000; // use any value between 0-65535 here vibration.wRightMotorSpeed = 16000; // use any value between 0-65535 here XInputSetState( i, &vibration );

请注意,右电机是高频电机,左电机是低频电机。 它们并不总是需要设置为相同的数量,因为它们提供不同的效果。

获取音频设备标识符

Xbox 控制器的头戴显示设备具有以下功能:

使用麦克风录制声音 使用耳机播放声音

使用此代码获取头戴显示设备的设备标识符:

WCHAR renderId[ 256 ] = {0}; WCHAR captureId[ 256 ] = {0}; UINT rcount = 256; UINT ccount = 256; XInputGetAudioDeviceIds( i, renderId, &rcount, captureId, &ccount );

获取设备标识符后,可以创建相应的接口。 例如,如果使用 XAudio 2.8,请使用以下代码为此设备创建主语音:

IXAudio2* pXAudio2 = NULL; HRESULT hr; if ( FAILED(hr = XAudio2Create( &pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR ) ) ) return hr; IXAudio2MasteringVoice* pMasterVoice = NULL; if ( FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0, renderId, NULL, AudioCategory_Communications ) ) ) return hr;

有关如何使用 captureId 设备标识符的信息,请参阅 捕获流。

仅 (旧版 DirectX SDK 获取 DirectSound GUID)

可以连接到 Xbox 控制器的耳机有两个功能:可以使用麦克风录制声音,以及使用耳机播放声音。 在 XInput API 中,这些函数使用 IDirectSound8 和 IDirectSoundCapture8 接口通过 DirectSound 实现。

若要将耳机麦克风和耳机与其相应的 DirectSound 接口相关联,必须通过调用 XInputGetDSoundAudioDeviceGuids 获取捕获和呈现设备的 DirectSoundGUID。

注意

不建议使用旧版 DirectSound ,在 Windows 应用商店应用中不可用。 本部分中的信息仅适用于 XInput (XInput 1.3) 的 DirectX SDK 版本。 XInput (XInput 1.4) 的Windows 8版本专门使用 Windows 音频会话 API (WASAPI) 通过 XInputGetAudioDeviceIds 获取的设备标识符。

XInputGetDSoundAudioDeviceGuids( i, &dsRenderGuid, &dsCaptureGuid );

检索 GUID 后,可以通过调用 DirectSoundCreate8 和 DirectSoundCaptureCreate8 来创建适当的接口,如下所示:

// Create IDirectSound8 using the controller's render device if( FAILED( hr = DirectSoundCreate8( &dsRenderGuid, &pDS, NULL ) ) ) return hr; // Set coop level to DSSCL_PRIORITY if( FAILED( hr = pDS->SetCooperativeLevel( hWnd, DSSCL_NORMAL ) ) ) return hr; // Create IDirectSoundCapture using the controller's capture device if( FAILED( hr = DirectSoundCaptureCreate8( &dsCaptureGuid, &pDSCapture, NULL ) ) ) return hr; 相关主题

编程参考



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有