Джойстики работают, как ожидалось, за исключением того, что, если они не подключены, мое приложение вылетает. Интересная вещь, я использовал его на компьютере, на котором я занимаюсь разработкой, он не трескает sh, когда он не подключен, только на других компьютерах. Так что нужно иметь в виду
Я использовал API следующим образом:
Я настраиваю глобальные переменные
LPDIRECTINPUTDEVICE8 JoystickDriver::joystick;
LPDIRECTINPUT8 JoystickDriver::di;
DIDEVCAPS JoystickDriver::capabilities;
HRESULT JoystickDriver::hr;
DIJOYSTATE2 JoystickDriver::jstate;
В функции обратного вызова, которая выполняется в фиксированный временной шаг
Основной обратный вызов:
if (*isInitialized != 1 )
{
js->initialize();
js->selectJoystick();
js->setProperties();
js->enumAxes();
*isInitialized = 1;
}
if (js->PollData(&Joystick::jstate) == S_OK)
{
slider[0] = (real_T)(1000 - Joystick::jstate.rglSlider[0]) / 20;
pov[0] = (real_T)Joystick::jstate.lX;
pov[1] = (real_T)Joystick::jstate.lY;
pov[2] = (real_T)Joystick::jstate.lRz;
Buttons[0] = (uint8_T)(Joystick::jstate.rgbButtons[0] & 0x80);
Buttons[1] = (uint8_T)(Joystick::jstate.rgbButtons[1] & 0x80);
Buttons[2] = (uint8_T)(Joystick::jstate.rgbButtons[2] & 0x80);
Buttons[3] = (uint8_T)(Joystick::jstate.rgbButtons[3] & 0x80);
Buttons[4] = (uint8_T)(Joystick::jstate.rgbButtons[4] & 0x80);
}
В определении / реализации класса
Joystick.h
class Joystick
{
public:
Joystick();
~Joystick();
HRESULT initialize();
HRESULT selectJoystick();
static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context);
HRESULT setProperties();
HRESULT enumAxes();
static BOOL CALLBACK enumAxesCallback(const DIDEVICEOBJECTINSTANCE* instance, VOID* context);
HRESULT PollData(DIJOYSTATE2 *js);
void disConnectJoystick();
static LPDIRECTINPUTDEVICE8 joystick;
static LPDIRECTINPUT8 di;
static DIDEVCAPS capabilities;
static HRESULT hr;
static DIJOYSTATE2 jstate;
};
Джойстик. cpp
#include "Joystick.h"
Joystick::Joystick()
{
}
Joystick::~Joystick()
{
}
HRESULT Joystick::initialize()
{
// Create a DirectInput device
if (FAILED(Joystick::hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&(Joystick::di), NULL)))
{
return Joystick::hr;
}
else
return E_FAIL;
}
HRESULT Joystick::selectJoystick()
{
// Look for the first simple joystick we can find.
if (FAILED(Joystick::hr = this->di->EnumDevices(DI8DEVCLASS_GAMECTRL, &Joystick::enumCallback, NULL, DIEDFL_ATTACHEDONLY)))
{
return Joystick::hr;
}
// Make sure we got a joystick
if (Joystick::joystick == NULL) {
printf("Joystick not found.\n");
return E_FAIL;
}
return Joystick::hr;
}
BOOL CALLBACK Joystick::enumCallback(const DIDEVICEINSTANCE* instance, VOID* context)
{
// Obtain an interface to the enumerated joystick.
Joystick::hr = (Joystick::di)->CreateDevice(instance->guidInstance, &Joystick::joystick, NULL);
// If it failed, then we can't use this joystick. (Maybe the user unplugged
// it while we were in the middle of enumerating it.)
if (FAILED(Joystick::hr)) {
return DIENUM_CONTINUE;
}
// Stop enumeration. Note: we're just taking the first joystick we get. You
// could store all the enumerated joysticks and let the user pick.
return DIENUM_STOP;
}
HRESULT Joystick::setProperties()
{
if (FAILED(Joystick::hr = Joystick::joystick->SetDataFormat(&c_dfDIJoystick2)))
{
return Joystick::hr;
}
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
if (FAILED(Joystick::hr = Joystick::joystick->SetCooperativeLevel(NULL, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
{
return Joystick::hr;
}
// Determine how many axis the joystick has (so we don't error out setting
// properties for unavailable axis)
Joystick::capabilities.dwSize = sizeof(DIDEVCAPS);
if (FAILED(Joystick::hr = Joystick::joystick->GetCapabilities(&Joystick::capabilities)))
{
return Joystick::hr;
}
return E_FAIL;
}
HRESULT Joystick::enumAxes()
{
if (FAILED(Joystick::hr = Joystick::joystick->EnumObjects(Joystick::enumAxesCallback, NULL, DIDFT_AXIS)))
{
return Joystick::hr;
}
else
return Joystick::hr;
}
BOOL CALLBACK Joystick::enumAxesCallback(const DIDEVICEOBJECTINSTANCE* instance, VOID* context)
{
HWND hDlg = (HWND)context;
DIPROPRANGE propRange;
propRange.diph.dwSize = sizeof(DIPROPRANGE);
propRange.diph.dwHeaderSize = sizeof(DIPROPHEADER);
propRange.diph.dwHow = DIPH_BYID;
propRange.diph.dwObj = instance->dwType;
propRange.lMin = -1000;
propRange.lMax = +1000;
// Set the range for the axis
if (FAILED(Joystick::joystick->SetProperty(DIPROP_RANGE, &propRange.diph)))
{
return DIENUM_STOP;
}
return DIENUM_CONTINUE;
}
HRESULT Joystick::PollData(DIJOYSTATE2 *js)
{
if (Joystick::joystick == NULL) {
return S_OK;
}
// Poll the device to read the current state
Joystick::hr = Joystick::joystick->Poll();
if (FAILED(Joystick::hr))
{
// DInput is telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We
// just re-acquire and try again.
Joystick::hr = Joystick::joystick->Acquire();
while (Joystick::hr == DIERR_INPUTLOST)
{
Joystick::hr = Joystick::joystick->Acquire();
}
// If we encounter a fatal error, return failure.
if ((Joystick::hr == DIERR_INVALIDPARAM) || (Joystick::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 (Joystick::hr == DIERR_OTHERAPPHASPRIO)
{
return S_OK;
}
}
// Get the input's device state
if (FAILED(Joystick::hr = Joystick::joystick->GetDeviceState(sizeof(DIJOYSTATE2), js)))
{
return Joystick::hr; // The device should have been acquired during the Poll()
}
return S_OK;
}
void Joystick::disConnectJoystick()
{
if (Joystick::joystick)
{
Joystick::joystick->Unacquire();
}
}