1
0
mirror of synced 2024-07-03 01:20:35 +00:00
G940LEDControl/LogitechSDK/SteeringWheel/Src/LogiControllerProperties.cpp

503 lines
16 KiB
C++

#include "LogiControllerProperties.h"
#include <dbt.h>
#include <map>
using namespace LogitechSteeringWheel;
CONST LPTSTR LGMSGPIPE_WINDOWCLASS = _T("Logitech Wingman Internal Message Router");
std::map<DWORD, ControllerPropertiesData> g_currentProperties;
std::map<DWORD, BOOL> g_setIsNecessary;
std::map<DWORD, BOOL> g_getIsNecessary;
WNDPROC g_SteeringWheelSDKOldWnd;
LRESULT CALLBACK NewSteeringWheelSDKWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
ControllerProperties::ControllerProperties(HWND hwnd)
{
m_gameHWnd = hwnd;
ZeroMemory(&m_defaultControllerProperties, sizeof(m_defaultControllerProperties));
ZeroMemory(&m_preferredControllerProperties, sizeof(m_preferredControllerProperties));
m_hadToStartEMon = FALSE;
SetDefaults();
m_preferredControllerProperties = m_defaultControllerProperties;
m_currentVersionSupportsGetSetProperties = FALSE;
// Check Logitech Gaming Software version
ZeroMemory(&m_wingmanVersion, sizeof(m_wingmanVersion));
if (SUCCEEDED(m_gamingSoftwareManager.GetWingmanSWVersion(m_wingmanVersion)))
{
if (m_wingmanVersion.major == 5 && m_wingmanVersion.minor >= 3
|| m_wingmanVersion.major > 5)
{
m_currentVersionSupportsGetSetProperties = TRUE;
}
//else
//{
//TRACE(_T("WARNING: current Gaming Software version is older than 5.03 and does not support get/set properties.\n"));
//TRACE(_T("Please install Logitech Gaming Software 5.03 or newer.\n"));
//}
}
else
{
// Let's suppose the following
m_currentVersionSupportsGetSetProperties = TRUE;
}
// saw this on Vista 64, so let's deal with it
if (0 == m_wingmanVersion.major)
{
m_currentVersionSupportsGetSetProperties = TRUE;
}
// Start Wingman gaming software if necessary
if (START_LOGITECH_SOFTWARE)
{
if (!m_gamingSoftwareManager.IsEventMonitorRunning())
{
// Only start event monitor if it supports getting and setting properties
if (m_currentVersionSupportsGetSetProperties)
{
m_gamingSoftwareManager.StartEventMonitor();
m_hadToStartEMon = TRUE;
}
}
}
//Replace the Window Procedure and Store the Old Window Procedure
g_SteeringWheelSDKOldWnd = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (__int3264)(LONG_PTR)NewSteeringWheelSDKWindowProc);
}
ControllerProperties::~ControllerProperties()
{
if (m_hadToStartEMon)
{
m_gamingSoftwareManager.StopEventMonitor();
}
}
HRESULT ControllerProperties::SetPreferred(ControllerPropertiesData properties)
{
// Check propertiesData to see if there isn't anything wrong.
if ((properties.defaultSpringEnabled != TRUE
&& properties.defaultSpringEnabled != FALSE)
|| (properties.forceEnable != TRUE
&& properties.forceEnable != FALSE)
|| (properties.damperGain < LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MIN
&& properties.damperGain > LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MAX)
|| (properties.defaultSpringGain < LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MIN
&& properties.defaultSpringGain > LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MAX)
|| (properties.overallGain < LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MIN
&& properties.overallGain > LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MAX)
|| (properties.springGain < LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MIN
&& properties.springGain > LG_CONTROL_PANEL_PROPERTIES_ATTENUATION_MAX)
|| (properties.combinePedals != TRUE
&& properties.combinePedals != FALSE)
|| (properties.wheelRange < LG_CONTROL_PANEL_PROPERTIES_OPERATING_RANGE_MIN
&& properties.wheelRange > LG_CONTROL_PANEL_PROPERTIES_OPERATING_RANGE_MAX))
{
_ASSERT(NULL);
return E_INVALIDARG;
}
// Check version
if (m_wingmanVersion.major == 5 && m_wingmanVersion.minor >= 3
|| m_wingmanVersion.major > 5)
{
// version is good
}
else
{
return E_FAIL;
}
if (!ControllerPropertiesAreEqual(m_preferredControllerProperties, properties))
{
std::map <DWORD,BOOL>::iterator itr_;
for(itr_ = g_setIsNecessary.begin();itr_!=g_setIsNecessary.end();itr_++)
{
g_setIsNecessary[itr_->first] = TRUE;
}
}
m_preferredControllerProperties = properties;
return S_OK;
}
//VOID ControllerProperties::SetPreferred(CONST DWORD controllerPID, CONST ControllerSetProperty deviceSetProperty, CONST INT value)
//{
// if (deviceSetProperty < PROPERTY_ALL
// || deviceSetProperty >= PROPERTY_NUMBER)
// {
// //Utils::LogiTrace(_T("Error: invalid argument given to ControllerProperties::SetPreferred(...)\n"));
// _ASSERT(NULL);
// return;
// }
//
// // Check version
// if (m_wingmanVersion.major == 5 && m_wingmanVersion.minor >= 3
// || m_wingmanVersion.major > 5)
// {
// // version is good
// }
// else
// {
// return;
// }
//
// ControllerPropertiesSetData propertiesSetData_;
// ZeroMemory(&propertiesSetData_, sizeof(propertiesSetData_));
//
// propertiesSetData_.size = sizeof(ControllerPropertiesSetData);
// propertiesSetData_.propertyToSet = deviceSetProperty;
// propertiesSetData_.versionNbr = VERSION_NUMBER_PROPERTIES;
// propertiesSetData_.productID = controllerPID;
// propertiesSetData_.properties = m_defaultControllerProperties;
//
// switch(deviceSetProperty)
// {
// case PROPERTY_OVERALL_GAIN:
// propertiesSetData_.properties.overallGain = value;
// break;
// case PROPERTY_SPRING_GAIN:
// propertiesSetData_.properties.springGain = value;
// break;
// case PROPERTY_DAMPER_GAIN:
// propertiesSetData_.properties.damperGain = value;
// break;
// case PROPERTY_FORCE_ENABLE:
// propertiesSetData_.properties.forceEnable = value;
// break;
// case PROPERTY_COMBINED_PEDALS:
// propertiesSetData_.properties.combinePedals = value;
// break;
// case PROPERTY_WHEEL_RANGE:
// propertiesSetData_.properties.wheelRange = value;
// break;
// default:
// _ASSERT(NULL);
// }
//
// COPYDATASTRUCT myCDS_;
// myCDS_.dwData = JOY_CONTROL_PANEL_SET_PROPERTIES ;
// myCDS_.cbData = sizeof(propertiesSetData_);
// myCDS_.lpData = &propertiesSetData_;
//
// HWND hEventMonitor_ = ::FindWindow(LGMSGPIPE_WINDOWCLASS, NULL);
// if (!hEventMonitor_)
// {
// //Utils::LogiTrace(_T("ControllerProperties::SetPreferred(): Didn't get the event monitor...\n"));
// return;
// }
// else
// {
// ::SendMessage(hEventMonitor_, WM_COPYDATA, (WPARAM)(HWND)m_gameHWnd, (LPARAM)(LPVOID)&myCDS_);
//
// g_setIsNecessary = TRUE;
// }
//}
VOID ControllerProperties::GetDefault(ControllerPropertiesData& properties)
{
properties = m_defaultControllerProperties;
}
HRESULT ControllerProperties::GetASync(CONST DWORD controllerPID)
{
ControllerPropertiesGetData propertiesGetData_;
ZeroMemory(&propertiesGetData_, sizeof(propertiesGetData_));
propertiesGetData_.size = sizeof(ControllerPropertiesGetData);
propertiesGetData_.versionNbr = VERSION_NUMBER_PROPERTIES;
propertiesGetData_.productID = controllerPID;
propertiesGetData_.properties = m_defaultControllerProperties;
COPYDATASTRUCT myCDS_;
myCDS_.dwData = JOY_CONTROL_PANEL_GET_PROPERTIES ;
myCDS_.cbData = sizeof(propertiesGetData_);
myCDS_.lpData = &propertiesGetData_;
HWND hEventMonitor_ = ::FindWindow(LGMSGPIPE_WINDOWCLASS, NULL);
if (!hEventMonitor_)
{
return E_FAIL;
}
else
{
::SendMessage(hEventMonitor_, WM_COPYDATA, (WPARAM)(HWND)m_gameHWnd, (LPARAM)(LPVOID)&myCDS_);
}
return S_OK;
}
BOOL ControllerProperties::GetCurrent(CONST DWORD controllerPID, ControllerPropertiesData& properties)
{
if (0 == g_currentProperties.count(controllerPID))
{
GetDefault(properties);
return FALSE;
}
else
{
properties = g_currentProperties[controllerPID];
return TRUE;
}
}
BOOL ControllerProperties::ControllerPropertiesAreEqual(CONST ControllerPropertiesData properties1, CONST ControllerPropertiesData properties2, CONST BOOL ignoreWheelRange)
{
if (properties1.forceEnable == properties2.forceEnable
&& properties1.defaultSpringEnabled == properties2.defaultSpringEnabled
&& properties1.damperGain == properties2.damperGain
&& properties1.overallGain == properties2.overallGain
&& properties1.springGain == properties2.springGain
&& properties1.combinePedals == properties2.combinePedals)
{
if (ignoreWheelRange)
{
return TRUE;
}
else
{
if (properties1.wheelRange == properties2.wheelRange)
{
return TRUE;
}
}
}
return FALSE;
}
VOID ControllerProperties::SetDefaults()
{
m_defaultControllerProperties.defaultSpringEnabled = FALSE;
m_defaultControllerProperties.forceEnable = TRUE;
m_defaultControllerProperties.damperGain = 100;
m_defaultControllerProperties.defaultSpringGain = 100;
m_defaultControllerProperties.overallGain = 100;
m_defaultControllerProperties.springGain= 100;
// We have separate pedals by default since 5.01
m_defaultControllerProperties.combinePedals = TRUE;
WingmanSoftwareVersion version_;
if (SUCCEEDED(m_gamingSoftwareManager.GetWingmanSWVersion(version_)))
{
if (version_.major == 5 && version_.minor >= 1
|| version_.major > 5)
{
m_defaultControllerProperties.combinePedals = FALSE;
}
}
else
{
m_defaultControllerProperties.combinePedals = FALSE;
}
m_defaultControllerProperties.wheelRange = 200;
m_defaultControllerProperties.gameSettingsEnabled = TRUE;
m_defaultControllerProperties.allowGameSettings = TRUE;
}
INT ControllerProperties::GetShifterMode(CONST LPDIRECTINPUTDEVICE8 device)
{
INT isShifterGated_ = -1;
if (NULL != device)
{
ShifterData shifterData_;
ZeroMemory(&shifterData_, sizeof(shifterData_));
shifterData_.size = sizeof(ShifterData);
shifterData_.versionNbr = VERSION_NUMBER_SHIFTER_MODE;
shifterData_.isGated = -1;
DIEFFESCAPE data_;
ZeroMemory(&data_, sizeof(data_));
data_.dwSize = sizeof(DIEFFESCAPE);
data_.dwCommand = ESCAPE_COMMAND_GATED_SHIFTER_MODE;
data_.lpvInBuffer = &shifterData_;
data_.cbInBuffer = sizeof(shifterData_);
HRESULT hr_ = E_FAIL;
if (SUCCEEDED(hr_ = device->Escape(&data_)))
{
isShifterGated_ = -1;
if (sizeof(INT) == data_.cbOutBuffer)
{
INT* returnValue_ = (INT*)data_.lpvOutBuffer;
if (NULL != returnValue_)
{
isShifterGated_ = *returnValue_;
}
}
}
else
{
//TRACE(_T("ERROR: escape returned error: 0x%x\n"), hr_);
}
}
return isShifterGated_;
}
BOOL ControllerProperties::IsMultiturnCapable(CONST DWORD controllerPID)
{
// Multiturn wheel PIDs
CONST DWORD PID_G27 = 0xC29B;
CONST DWORD PID_G25 = 0xC299;
CONST DWORD PID_DRIVING_FORCE_PRO = 0xC298;
if (PID_G27 == controllerPID
|| PID_G25 == controllerPID
|| PID_DRIVING_FORCE_PRO == controllerPID)
{
return TRUE;
}
return FALSE;
}
VOID ControllerProperties::SendSetMessage(CONST DWORD controllerPID, CONST ControllerPropertiesData properties)
{
ControllerPropertiesSetData propertiesSetData_;
ZeroMemory(&propertiesSetData_, sizeof(propertiesSetData_));
propertiesSetData_.size = sizeof(ControllerPropertiesSetData);
propertiesSetData_.propertyToSet = PROPERTY_ALL;
propertiesSetData_.versionNbr = VERSION_NUMBER_PROPERTIES;
propertiesSetData_.productID = controllerPID;
propertiesSetData_.properties = properties;
COPYDATASTRUCT myCDS_;
myCDS_.dwData = JOY_CONTROL_PANEL_SET_PROPERTIES ;
myCDS_.cbData = sizeof(propertiesSetData_);
myCDS_.lpData = &propertiesSetData_;
HWND hEventMonitor_ = ::FindWindow(LGMSGPIPE_WINDOWCLASS, NULL);
if (!hEventMonitor_)
{
//TRACE(_T("SetPreferred: Event Monitor is not running\n"));
return;
}
else
{
::SendMessage(hEventMonitor_, WM_COPYDATA, (WPARAM)(HWND)m_gameHWnd, (LPARAM)(LPVOID)&myCDS_);
}
}
HRESULT ControllerProperties::Update(CONST std::vector<DWORD> currentlyConnectedPIDs)
{
// Check version
if (m_wingmanVersion.major == 5 && m_wingmanVersion.minor >= 3
|| m_wingmanVersion.major > 5)
{
// version is good
}
else
{
return E_NOTIMPL;
}
if (m_previouslyConnectedPIDs != currentlyConnectedPIDs)
{
for (UINT index_ = 0; index_ < currentlyConnectedPIDs.size(); index_++)
{
SendSetMessage(currentlyConnectedPIDs[index_], m_preferredControllerProperties);
g_setIsNecessary[currentlyConnectedPIDs[index_]] = FALSE;
g_getIsNecessary[currentlyConnectedPIDs[index_]] = TRUE;
}
}
for (UINT index_ = 0; index_ < currentlyConnectedPIDs.size(); index_++)
{
if (0 != g_getIsNecessary.count(currentlyConnectedPIDs[index_]))
{
if (g_getIsNecessary[currentlyConnectedPIDs[index_]])
{
GetASync(currentlyConnectedPIDs[index_]);
}
}
if (0 != g_setIsNecessary.count(currentlyConnectedPIDs[index_]))
{
if (g_setIsNecessary[currentlyConnectedPIDs[index_]])
{
SendSetMessage(currentlyConnectedPIDs[index_], m_preferredControllerProperties);
g_setIsNecessary[currentlyConnectedPIDs[index_]] = FALSE;
g_getIsNecessary[currentlyConnectedPIDs[index_]] = TRUE;
}
}
}
m_previouslyConnectedPIDs = currentlyConnectedPIDs;
return S_OK;
}
LRESULT CALLBACK NewSteeringWheelSDKWindowProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
BOOL activateValue_ = FALSE;
switch (message)
{
case WM_ACTIVATEAPP:
activateValue_ = static_cast<BOOL>(wParam);
if (activateValue_)
{
std::map <DWORD,BOOL>::iterator itr_;
for(itr_ = g_setIsNecessary.begin();itr_!=g_setIsNecessary.end();itr_++)
{
g_setIsNecessary[itr_->first] = TRUE;
}
}
break;
//case WM_TIMER:
// {
// switch (wParam)
// {
// case 0xacbd:
// }
// }
// break;
case WM_COPYDATA:
{
COPYDATASTRUCT* myCDS_ = (COPYDATASTRUCT *)lParam;
ControllerPropertiesGetData* properties_ = (ControllerPropertiesGetData*)myCDS_->lpData;
if (myCDS_->dwData == JOY_CONTROL_PANEL_GET_PROPERTIES)
{
g_currentProperties[properties_->productID] = properties_->properties;
g_getIsNecessary[properties_->productID] = FALSE;
}
}
break;
case WM_DEVICECHANGE:
{
std::map <DWORD,BOOL>::iterator itr_;
for(itr_ = g_setIsNecessary.begin();itr_!=g_setIsNecessary.end();itr_++)
{
g_setIsNecessary[itr_->first] = TRUE;
}
}
break;
default:
break;
}
return CallWindowProc (g_SteeringWheelSDKOldWnd, hwnd, message, wParam, lParam);
}