gpt4 book ai didi

c++ - 如何使用 Microsoft 的 IDirectInputDevice8 在 C++ 中使用 Joystick 代码?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:09:35 26 4
gpt4 key购买 nike

我需要使用 IDirectInputDevice8 接口(interface)进行阻塞和非阻塞调用以轮询直接输入设备。

在 linux 中做阻塞,我们使用 select 例如:

while( ::select(_jdev+1, &set, NULL, NULL, &tv) > 0) 
{
if( ::read( _jdev, &js, sizeof( js_event ) ) != sizeof( js_event ) )
{
perror( "Joystick : read error" );
return;
}

_handleEvent( js );
}

如何使用 idirectinputdevice8 接口(interface) 做同样的事情: https://msdn.microsoft.com/en-us/library/windows/desktop/ee417816(v=vs.85).aspx

即使我设置了 IDirectInputDevice8::SetEventNotification(),我仍然必须每次调用 poll() 来获取新数据,这不是可行的解决方案,因为它会导致 cpu 旋转。

我怎样才能做到这一点?

*** 目前,我可以从操纵杆设备中查找、迭代、连接和获取数据。我只是没有实现阻塞调用。

...这是我的实验/测试代码...请忽略语法错误

#include <windows.h>
#include <dinput.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include "joystick.h"


LPDIRECTINPUT8 di;
HRESULT hr;
LPDIRECTINPUTDEVICE8 joystick;
DIDEVCAPS capabilities;

BOOL CALLBACK
enumCallback(const DIDEVICEINSTANCE* instance, VOID* context)
{
HRESULT hr;
hr = di->CreateDevice(instance->guidInstance, &joystick, NULL);
if (FAILED(hr)) {
return DIENUM_CONTINUE;
}
return DIENUM_STOP;
}

int JoyStickProp()
{
if (FAILED(hr = joystick->SetDataFormat(&c_dfDIJoystick2))) {
return hr;
}
if (FAILED(hr = joystick->SetCooperativeLevel(NULL, DISCL_EXCLUSIVE |
DISCL_FOREGROUND))) {
return hr;
}
capabilities.dwSize = sizeof(DIDEVCAPS);
if (FAILED(hr = joystick->GetCapabilities(&capabilities))) {
return hr;
}
}

HRESULT JoyStickPoll(DIJOYSTATE2 *js)
{
HRESULT hr;

if (joystick == NULL) {
return S_OK;
}

// Poll the device to read the current state
hr = joystick->Poll();
if (FAILED(hr)) {
hr = joystick->Acquire();
while (hr == DIERR_INPUTLOST) {
hr = joystick->Acquire();
}

if ((hr == DIERR_INVALIDPARAM) || (hr == DIERR_NOTINITIALIZED)) {
return E_FAIL;
}

// If another application has control of this device, return successfully.
// We'll just have to wait our turn to use the joystick.
if (hr == DIERR_OTHERAPPHASPRIO) {
return S_OK;
}
}

// Get the input's device state
if (FAILED(hr = joystick->GetDeviceState(sizeof(DIJOYSTATE2), js))) {
return hr; // The device should have been acquired during the Poll()
}

return S_OK;
}

int main()
{


// Create a DirectInput device
if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&di, NULL))) {
return hr;
}

// Look for the first simple joystick we can find.
if (FAILED(hr = di->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback,
NULL, DIEDFL_ATTACHEDONLY))) {
return hr;
}
// Make sure we got a joystick
if (joystick == NULL) {
printf("Joystick not found.\n");
return E_FAIL;
}

JoyStickProp();
DIJOYSTATE2 diState;

HANDLE ghWriteEvent;
// Create joystick event stuff here
ghWriteEvent = CreateEvent(
NULL, // default security attributes
FALSE, // manual-reset event
FALSE, // initial state is nonsignaled
TEXT("WriteEvent") // object name
);

//makesure we can read fromt the joystick before waiting for an event
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
JoyStickPoll(&diState);
printf("x axis %d", diState.lX);
printf("y axis %d", diState.lY);
joystick->SetEventNotification(ghWriteEvent);
while (TRUE) {

DWORD dwResult = WaitForSingleObject(
ghWriteEvent, // event handle
INFINITE);

switch (dwResult) {
case WAIT_OBJECT_0:
// Event 1 has been set. If the event was created as
// autoreset, it has also been reset.
int x = 0;
//ProcessInputEvent1();
break;
}
}
}

最佳答案

IDirectInputDevice8::SetEventNotification() 的 MSDN 文档为您提供相关的代码片段。

您需要调用CreateEvent()并将返回的 HANDLE 作为参数提供给 SetEventNotification()。当发生状态更改时,将为您发出事件信号。您可以等待该事件,然后一旦收到通知,您就可以使用 IDirectInputDevice8::GetDeviceState() 获取新的状态数据。 .

所有标准Wait Functions适用于等待事件被发出信号。以下代码片段向您展示了一种方法,使用 MsgWaitForMultipleObjects() :

while (TRUE) { 

dwResult = MsgWaitForMultipleObjects(2, ah, FALSE, INFINITE, QS_ALLINPUT);
switch (dwResult) {
case WAIT_OBJECT_0:
// Event 1 has been set. If the event was created as
// autoreset, it has also been reset.
ProcessInputEvent1();
break;

IDirectInputDevice8::Poll()方法用于不生成事件通知的设备。您应该对它们进行轮询,因为它们无法按照您希望的方式运行。

Some joysticks and other game devices, or particular objects on them, do not generate hardware interrupts and do not return any data or signal any events until you call the IDirectInputDevice8::Poll method.

只有当通知对设备不起作用时,您才会在需要时进行轮询。上面的链接解释了如何确定是否需要轮询。

关于c++ - 如何使用 Microsoft 的 IDirectInputDevice8 在 C++ 中使用 Joystick 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43947007/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com