添加图马斯特摇杆控制功能框架,按钮未关联吊舱控制键
parent
07deb10cb4
commit
9a18ef852b
@ -0,0 +1,164 @@
|
|||||||
|
#include "DirectInputJoystick.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
DirectInputJoystick::DirectInputJoystick(QObject *parent) : QObject(parent) {
|
||||||
|
// 确保 COM 库在主线程初始化
|
||||||
|
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectInputJoystick::~DirectInputJoystick() {
|
||||||
|
cleanup();
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirectInputJoystick::initialize() {
|
||||||
|
HRESULT hr = DirectInput8Create(
|
||||||
|
GetModuleHandle(nullptr),
|
||||||
|
DIRECTINPUT_VERSION,
|
||||||
|
IID_IDirectInput8,
|
||||||
|
(VOID**)&m_pDirectInput,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
emit errorOccurred("无法创建 DirectInput 对象");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 枚举所有摇杆设备
|
||||||
|
hr = m_pDirectInput->EnumDevices(
|
||||||
|
DI8DEVCLASS_GAMECTRL,
|
||||||
|
enumJoysticksCallback,
|
||||||
|
this,
|
||||||
|
DIEDFL_ATTACHEDONLY
|
||||||
|
);
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CALLBACK DirectInputJoystick::enumJoysticksCallback(const DIDEVICEINSTANCE* instance, VOID* context) {
|
||||||
|
DirectInputJoystick* joystick = static_cast<DirectInputJoystick*>(context);
|
||||||
|
return joystick->setupDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirectInputJoystick::setupDevice() {
|
||||||
|
if (!m_pDirectInput) return false;
|
||||||
|
|
||||||
|
// 创建设备
|
||||||
|
HRESULT hr = m_pDirectInput->CreateDevice(
|
||||||
|
GUID_Joystick,
|
||||||
|
&m_pJoystick,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
emit errorOccurred("无法创建摇杆设备");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数据格式
|
||||||
|
hr = m_pJoystick->SetDataFormat(&c_dfDIJoystick);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
emit errorOccurred("设置数据格式失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置协作级别
|
||||||
|
hr = m_pJoystick->SetCooperativeLevel(
|
||||||
|
nullptr, // 无窗口句柄
|
||||||
|
DISCL_BACKGROUND | DISCL_NONEXCLUSIVE
|
||||||
|
);
|
||||||
|
|
||||||
|
// 枚举轴并设置范围
|
||||||
|
hr = m_pJoystick->EnumObjects(enumAxesCallback, this, DIDFT_AXIS);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
emit errorOccurred("枚举摇杆轴失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建事件对象
|
||||||
|
m_hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
hr = m_pJoystick->SetEventNotification(m_hEvent);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
emit errorOccurred("设置事件通知失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CALLBACK DirectInputJoystick::enumAxesCallback(const DIDEVICEOBJECTINSTANCE* doi, VOID* context) {
|
||||||
|
DirectInputJoystick* joystick = static_cast<DirectInputJoystick*>(context);
|
||||||
|
DIPROPRANGE diprg;
|
||||||
|
diprg.diph.dwSize = sizeof(DIPROPRANGE);
|
||||||
|
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||||
|
diprg.diph.dwHow = DIPH_BYID;
|
||||||
|
diprg.diph.dwObj = doi->dwType;
|
||||||
|
diprg.lMin = -1000;
|
||||||
|
diprg.lMax = 1000;
|
||||||
|
|
||||||
|
HRESULT hr = joystick->m_pJoystick->SetProperty(DIPROP_RANGE, &diprg.diph);
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectInputJoystick::startListening() {
|
||||||
|
if (!m_pJoystick || m_isRunning) return;
|
||||||
|
|
||||||
|
m_isRunning = true;
|
||||||
|
m_workerThread = QThread::create([this]() {
|
||||||
|
m_pJoystick->Acquire();
|
||||||
|
|
||||||
|
while (m_isRunning) {
|
||||||
|
WaitForSingleObject(m_hEvent, INFINITE);
|
||||||
|
|
||||||
|
DIJOYSTATE state;
|
||||||
|
HRESULT hr = m_pJoystick->GetDeviceState(sizeof(DIJOYSTATE), &state);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
// 处理轴数据
|
||||||
|
double x = state.lX / 1000.0;
|
||||||
|
double y = state.lY / 1000.0;
|
||||||
|
double z = state.lZ / 1000.0;
|
||||||
|
emit axisChanged(0, x);
|
||||||
|
emit axisChanged(1, y);
|
||||||
|
emit axisChanged(2, z);
|
||||||
|
|
||||||
|
// 处理按钮
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
if(lastState.rgbButtons[i]!=state.rgbButtons[i])
|
||||||
|
{
|
||||||
|
bool pressed = (state.rgbButtons[i] & 0x80) != 0;
|
||||||
|
|
||||||
|
emit buttonChanged(i, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(lastState.rgdwPOV[0]!=state.rgdwPOV[0])
|
||||||
|
{
|
||||||
|
emit directionChanged(state.rgdwPOV[0]/100);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastState = state;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_workerThread, &QThread::finished, m_workerThread, &QThread::deleteLater);
|
||||||
|
m_workerThread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectInputJoystick::cleanup() {
|
||||||
|
m_isRunning = false;
|
||||||
|
if (m_hEvent) {
|
||||||
|
CloseHandle(m_hEvent);
|
||||||
|
m_hEvent = nullptr;
|
||||||
|
}
|
||||||
|
if (m_pJoystick) {
|
||||||
|
m_pJoystick->Unacquire();
|
||||||
|
m_pJoystick->Release();
|
||||||
|
m_pJoystick = nullptr;
|
||||||
|
}
|
||||||
|
if (m_pDirectInput) {
|
||||||
|
m_pDirectInput->Release();
|
||||||
|
m_pDirectInput = nullptr;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue