161 lines
4.8 KiB
C++
161 lines
4.8 KiB
C++
|
/*
|
||
|
The Logitech Controller Input SDK, including all accompanying
|
||
|
documentation, is protected by intellectual property laws. All rights
|
||
|
not expressly granted by Logitech are reserved.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "LogiGameControllerDI.h"
|
||
|
#include "LogiControllerInputUtils.h"
|
||
|
|
||
|
using namespace LogitechControllerInput;
|
||
|
|
||
|
LogiGameControllerDI::LogiGameControllerDI(CONST INT index, CONST HWND gameHWnd)
|
||
|
{
|
||
|
m_ctrlNbr = index;
|
||
|
m_gameHWnd = gameHWnd;
|
||
|
m_isXInputDevice = FALSE;
|
||
|
|
||
|
Init();
|
||
|
}
|
||
|
|
||
|
VOID LogiGameControllerDI::Init()
|
||
|
{
|
||
|
ZeroMemory(&m_currentState, sizeof(m_currentState));
|
||
|
ZeroMemory(&m_previousState, sizeof(m_previousState));
|
||
|
|
||
|
for (INT ii = 0; ii < 4; ii++)
|
||
|
{
|
||
|
m_currentState.rgdwPOV[ii] = 0xffffffff;
|
||
|
m_previousState.rgdwPOV[ii] = 0xffffffff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT LogiGameControllerDI::Read()
|
||
|
{
|
||
|
HRESULT hr_ = E_FAIL;
|
||
|
|
||
|
if(NULL == m_device)
|
||
|
{
|
||
|
LOGICONTROLLERTRACE(_T("ERROR: trying to read a gaming device that doesn't have a handle\n"));
|
||
|
return hr_;
|
||
|
}
|
||
|
|
||
|
// Poll the device to read the current state
|
||
|
hr_ = m_device->Poll();
|
||
|
if( FAILED(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.
|
||
|
hr_ = m_device->Acquire();
|
||
|
|
||
|
if (SUCCEEDED(hr_))
|
||
|
{
|
||
|
// This only gets called once after window regains focus. This disables centering
|
||
|
// spring on Logitech wheels.
|
||
|
if (HasForceFeedback() && LG_DEVICE_TYPE_WHEEL == m_deviceType)
|
||
|
{
|
||
|
if (FAILED(hr_ = m_device->SendForceFeedbackCommand(DISFFC_SETACTUATORSON)))
|
||
|
{
|
||
|
LOGICONTROLLERTRACE(_T("WARNING: Controller nbr %d: failed to set actuators to ON\n"), m_ctrlNbr);
|
||
|
m_actuatorsAreOn = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_actuatorsAreOn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// hr_ may be DIERR_OTHERAPPHASPRIO or other errors. This
|
||
|
// may occur when the app is minimized or in the process of
|
||
|
// switching, so just try again later
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// Set actuators on. This command will take off the centering spring on the logitech wheel.
|
||
|
if (!m_actuatorsAreOn && HasForceFeedback() && LG_DEVICE_TYPE_WHEEL == m_deviceType)
|
||
|
{
|
||
|
if (FAILED(hr_ = m_device->SendForceFeedbackCommand(DISFFC_SETACTUATORSON)))
|
||
|
{
|
||
|
LOGICONTROLLERTRACE(_T("WARNING: Controller nbr %d: failed to set actuators to ON\n"), m_ctrlNbr);
|
||
|
m_actuatorsAreOn = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_actuatorsAreOn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Save the last position
|
||
|
m_previousState = m_currentState;
|
||
|
|
||
|
// Get the input's device state
|
||
|
if( FAILED( hr_ = m_device->GetDeviceState( sizeof(DIJOYSTATE2), &m_currentState ) ) )
|
||
|
{
|
||
|
LOGICONTROLLERTRACE(_T("WARNING: could not retrieve positional information for gaming device\n"));
|
||
|
if (hr_ == DIERR_INPUTLOST)
|
||
|
{
|
||
|
//TRACE(_T("Gaming device got unplugged!\n"));
|
||
|
ZeroMemory(&m_currentState, sizeof(m_currentState));
|
||
|
for (INT ii = 0; ii < 4; ii++)
|
||
|
{
|
||
|
m_currentState.rgdwPOV[ii] = 0xffffffff;
|
||
|
}
|
||
|
}
|
||
|
return hr_; // The device should have been acquired during the Poll()
|
||
|
}
|
||
|
|
||
|
// For some bloody reason, XInput gamepads report their Y axes on both left and right ministick the opposite than DInput devices.
|
||
|
// So let's invert the DInput gamepad ministick Y axes in order to get it all the same...
|
||
|
if (LG_DEVICE_TYPE_GAMEPAD == m_deviceType)
|
||
|
{
|
||
|
m_currentState.lY = -m_currentState.lY - 1;
|
||
|
m_currentState.lRz = -m_currentState.lRz - 1;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
DIJOYSTATE2* LogiGameControllerDI::GetStateDInput()
|
||
|
{
|
||
|
return &m_currentState;
|
||
|
}
|
||
|
|
||
|
BOOL LogiGameControllerDI::ButtonIsPressed(INT buttonNbr)
|
||
|
{
|
||
|
return (m_currentState.rgbButtons[buttonNbr] & 0x80 );
|
||
|
}
|
||
|
|
||
|
BOOL LogiGameControllerDI::ButtonTriggered(INT buttonNbr)
|
||
|
{
|
||
|
return (!(m_previousState.rgbButtons[buttonNbr] & 0x80) &&
|
||
|
(m_currentState.rgbButtons[buttonNbr] & 0x80));
|
||
|
}
|
||
|
|
||
|
BOOL LogiGameControllerDI::ButtonReleased(INT buttonNbr)
|
||
|
{
|
||
|
return ((m_previousState.rgbButtons[buttonNbr] & 0x80) &&
|
||
|
!(m_currentState.rgbButtons[buttonNbr] & 0x80));
|
||
|
}
|
||
|
|
||
|
BOOL LogiGameControllerDI::HasForceFeedback()
|
||
|
{
|
||
|
if (m_numFFAxes > 0)
|
||
|
return TRUE;
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
VOID LogiGameControllerDI::SetNumberFFAxes(INT number)
|
||
|
{
|
||
|
m_numFFAxes = number;
|
||
|
}
|
||
|
|
||
|
INT LogiGameControllerDI::GetNumberFFAxes()
|
||
|
{
|
||
|
return m_numFFAxes;
|
||
|
}
|