1
0
mirror of synced 2024-07-05 10:00:35 +00:00
G940LEDControl/LogitechSDK/ControlsAssignment/Src/LogiControlsAssignment.cpp

782 lines
26 KiB
C++

/****f* Controls.Assignment.SDK/ControlsAssignmentSDK[1.00.002]
* NAME
* Controls Assignment SDK
* COPYRIGHT
* The Logitech Controls Assignment SDK, including all
* accompanying documentation, is protected by intellectual property
* laws. All rights not expressly granted by Logitech are reserved.
* PURPOSE
* The Controls Assignment SDK enables developers to easily and
* quickly create a bulletproof solution for assigning any controls
* of any game controller to any functionality in their PC game. The
* wrapper also enables to directly calculate combined values for
* pairs of game actions so the developer can directly feed the
* values into his game.
* The wrapper is an addition to Microsoft's DirectInput and XInput
* and supports both.
*
* See the following files to get started:
* - readme.txt: tells you how to get started.
* - Doc/SampleInGameImplementation.cpp: shows line by line how to
* use the Controls Assignment SDK's interface to implement
* control assignment in your game.
* - Samples/ControlsAssignmentSDKDemo: VS2005 sample project that demonstrates
* control assignment.
* Just compile, run and plug in up to 4 DirectX or XInput
* compatible game controllers (steering wheel, joystick,
* gamepad, etc.).
* NOTES
* The Controls Assignment SDK uses the Logitech Controller Input
* Wrapper (included in the package), which provides a simple
* interface to:
* - support both DirectInput and XInput hot plug/unplug
* - integrate DInput and Xinput support seamlessly
* - get controller positional information as well as general
* info such as friendly name, VID, PID, connection status based
* on various parameters such as controller type,manufacturer,
* and model name, and whether it supports force feedback/rumble.
* - get hooks to add force feedback or rumble (DirectInput
* device interface and XInput ID).
* For more details see Microsoft's DirectInput and XInput
* documentation.
* AUTHOR
* Christophe Juncker (cj@wingmanteam.com)
******
*/
#include "LogiControlsAssignment.h"
#include "LogiControlsAssignmentUtils.h"
#include <vector>
using namespace LogitechControlsAssignmentSDK;
using namespace LogitechControllerInput;
/****f* Controls.Assignment.SDK/ControlsAssignment(ControllerInput*.controllerInput,LONG.axesDInputRangeMin,LONG.axesDInputRangeMax)
* NAME
* ControlsAssignment(ControllerInput* controllerInput, LONG
* axesDInputRangeMin, LONG axesDInputRangeMax) -- Does necessary
* initialization.
* INPUTS
* controllerInput: handle to instance of Controller Input SDK.
*
* axesDInputRangeMin: minimum value to be used by DirectInput for
* axes. Should be -32768 to be consistent with XInput.
*
* axesDInputRangeMax: maximum value to be used by DirectInput for
* axes. Should b 32767 to be consistent with XInput.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
ControlsAssignment::ControlsAssignment(ControllerInput* controllerInput, CONST LONG axesDInputRangeMin, CONST LONG axesDInputRangeMax)
{
for (INT ii = 0; ii < LG_MAX_NUMBER_SUPPORTED_CONTROLLERS; ii++)
{
m_controllerDInput[ii].Init(axesDInputRangeMin, axesDInputRangeMax);
}
_ASSERT(NULL != controllerInput);
m_controllerInput = controllerInput;
}
ControlsAssignment::~ControlsAssignment()
{
for (UINT ii = 0; ii < m_gameActions.size(); ii++)
{
delete m_gameActions[ii];
}
}
/****f* Controls.Assignment.SDK/AddGameAction(INT.gameActionID)
* NAME
* HRESULT AddGameAction(INT gameActionID) -- Add a game action (such
* as for example Turn Left, or Shoot).
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* NOTES
* Every game action needs to be added during initialization.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::AddGameAction(CONST INT gameActionID)
{
GameAction* action_ = new GameAction();
if (NULL == action_)
return E_FAIL;
action_->SetID(gameActionID);
m_gameActions.insert(std::make_pair(gameActionID, action_));
return S_OK;
}
GameAction* ControlsAssignment::GetGameAction(CONST INT gameActionID)
{
ActionMap::iterator it_ = m_gameActions.find(gameActionID);
if (it_ == m_gameActions.end())
{
return NULL;
}
return it_->second;
}
/****f* Controls.Assignment.SDK/StartCheckingForInput(INT.gameActionID)
* NAME
* HRESULT StartCheckingForInput(INT gameActionID) -- This needs to be
* called to indicate that the game action is now in the state where
* it is checking for a control to be moved.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::StartCheckingForInput(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
return E_FAIL;
gameAction_->StartCheckingForInput();
// Set all initial values for axes.
for (INT kk = 0; kk < LG_MAX_NUMBER_SUPPORTED_CONTROLLERS; kk++)
{
m_controllerDInput[kk].SetInitialValues();
m_controllerXInput[kk].SetInitialValues();
}
return S_OK;
}
/****f* Controls.Assignment.SDK/StopCheckingForInput(INT.gameActionID)
* NAME
* HRESULT StopCheckingForInput(INT gameActionID) -- Stop checking for
* input. If it is necessary to stop checking for input without having
* assigned a control, call this function.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::StopCheckingForInput(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
return E_FAIL;
if (NULL != gameAction_)
{
gameAction_->StopCheckingForInput();
}
return S_OK;
}
/****f* Controls.Assignment.SDK/IsCheckingForInput(INT.gameActionID)
* NAME
* BOOL IsCheckingForInput(INT gameActionID) -- Indicates whether the
* wrapper is currently in the state where it is checking for a
* control to be moved.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* TRUE if the wrapper is currently checking for controller movement.
* FALSE otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
BOOL ControlsAssignment::IsCheckingForInput(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
{
LOGIASSIGNTRACE(_T("ERROR: ControlsAssignment::IsCheckingForInput"));
return FALSE;
}
return gameAction_->IsCheckingForInput();
}
/****f* Controls.Assignment.SDK/IsGameActionAssigned(INT.gameActionID)
* NAME
* BOOL IsGameActionAssigned(INT gameActionID) -- Indicates whether
* the game action has a control assigned to it.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* TRUE if the corresponding game action has a control assigned.
* FALSE otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
BOOL ControlsAssignment::IsGameActionAssigned(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
{
return FALSE;
}
if (NULL != gameAction_->GetControl())
{
return TRUE;
}
return FALSE;
}
/****f* Controls.Assignment.SDK/GetValue(INT.gameActionID)
* NAME
* FLOAT GetValue(INT gameActionID) -- Returns current value of the
* game action (0.0 or 1.0 for buttons and POVs, 0.0 to 1.0 or -1.0 to
* 0.0 for axes).
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* Current value of the game action if a control is assigned to it.
* 0.0 otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
FLOAT ControlsAssignment::GetValue(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
{
return 0.0f;
}
return gameAction_->GetValue();
}
/****f* Controls.Assignment.SDK/GetCombinedValue(INT.gameAction1ID,INT.gameAction2ID,BOOL.reverseFlag)
* NAME
* FLOAT GetCombinedValue(INT gameAction1ID, INT gameAction2ID, BOOL
* reverseFlag) -- Returns a value that is the combination of 2 game
* actions. For example if giving it Turn Left and Turn Right, the
* return value will be the combination of those two actions. If the
* reverseFlag is set, the return value will be inverted.
* INPUTS
* gameAction1ID: identification number of the first game action.
*
* gameAction2ID: identification number of the second game action.
*
* reverseFlag: indicates whether output should be inverted.
* RETURN VALUE
* Combined value of 2 game actions.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
FLOAT ControlsAssignment::GetCombinedValue(CONST INT gameAction1ID, CONST INT gameAction2ID, CONST BOOL reverseFlag)
{
GameAction* gameAction1_ = GetGameAction(gameAction1ID);
GameAction* gameAction2_ = GetGameAction(gameAction2ID);
if (NULL == gameAction1_ || NULL == gameAction2_)
{
return 0.0f;
}
return Utils::Combine(gameAction1_->GetControl(), gameAction2_->GetControl(), reverseFlag);
}
/****f* Controls.Assignment.SDK/GetControlName(INT.gameActionID)
* NAME
* LPCTSTR GetControlName(INT gameActionID) -- Get name of the control
* assigned to the current game action.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* Name of the control assigned to the current game action.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
LPCTSTR ControlsAssignment::GetControlName(CONST INT gameActionID)
{
static TCHAR name_[MAX_PATH];
ZeroMemory(name_, sizeof(name_));
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
return _T("");
Control* control_ = gameAction_->GetControl();
if (NULL == control_)
return _T("");
if (control_->GetControllerType() == LG_CONTROLLER_TYPE_DINPUT)
{
if (SUCCEEDED(GetControlNameDInput(name_, control_)))
{
return name_;
}
}
else if (control_->GetControllerType() == LG_CONTROLLER_TYPE_XINPUT)
{
if (SUCCEEDED(GetControlNameXInput(name_, control_)))
{
return name_;
}
}
return _T("");
}
/****f* Controls.Assignment.SDK/Update()
* NAME
* HRESULT Update() -- Updates all axes, buttons and POVs inside the
* wrapper. Calculates their normalized values depending on the
* minimum and maximum output of DirectInput or default values for
* XInput. If an action is currently in the special state where it
* checks for controller movement, this function assigns a control to
* the game action and leaves the special state. Use
* IsGameActionAssigned() to check if the wrapper still is in the
* special state or not. If another game action had the same control
* assigned, it gets reset.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* SEE ALSO
* IsGameActionAssigned(INT.gameActionID)
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::Update()
{
if (NULL == m_controllerInput)
return E_FAIL;
// Do the update on DInput and XInput devices. Check the
// controller number in the input, and assign to corresponding
// DInput or XInput controller structure.
for (INT index_ = 0; index_ < LG_MAX_NUMBER_SUPPORTED_CONTROLLERS; index_++)
{
if (m_controllerInput->IsConnected(index_))
{
if (m_controllerInput->IsXInputDevice(index_))
{
if (FAILED(m_controllerXInput[index_].Update(index_, m_controllerInput->GetStateXInput(index_))))
return E_FAIL;
}
else
{
// it's a DirectInput device
if (FAILED(m_controllerDInput[index_].Update(index_, m_controllerInput->GetStateDInput(index_))))
return E_FAIL;
}
}
}
INT counter1_ = 0;
ActionMap::iterator it1_;
for( it1_ = m_gameActions.begin(); it1_ != m_gameActions.end(); it1_++ )
{
++counter1_;
GameAction* currAction1_ = it1_->second;
if (currAction1_->IsCheckingForInput())
{
Control* tempControl_ = NULL;
// Check each controller to see if any control moved
for (INT kk = 0; kk < LG_MAX_NUMBER_SUPPORTED_CONTROLLERS; kk++)
{
tempControl_ = m_controllerDInput[kk].ControlMoved();
if (NULL == tempControl_)
tempControl_ = m_controllerXInput[kk].ControlMoved();
if (NULL != tempControl_)
break;
}
if (NULL != tempControl_)
{
currAction1_->SetControl(tempControl_);
INT counter2_ = 0;
// Make sure there are no conflicts by resetting other game actions' control if it's the same
ActionMap::iterator it2_;
for( it2_ = m_gameActions.begin(); it2_ != m_gameActions.end(); it2_++ )
{
++counter2_;
if (counter1_ != counter2_)
{
GameAction* currAction2_ = it2_->second;
currAction2_->ResetIfSameControl(currAction1_->GetControl());
}
}
}
}
}
return S_OK;
}
/****f* Controls.Assignment.SDK/Reset(INT.gameActionID)
* NAME
* HRESULT Reset(INT gameActionID) -- Resets a game action.
* INPUTS
* gameActionID: identification number of the game action.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::Reset(CONST INT gameActionID)
{
GameAction* gameAction_ = GetGameAction(gameActionID);
if (NULL == gameAction_)
return E_FAIL;
gameAction_->SetControl(NULL);
return S_OK;
}
HRESULT ControlsAssignment::GetControlNameDInput(LPTSTR name, Control* control)
{
if (NULL == control)
{
_tcscpy_s(name, MAX_PATH, _T(""));
return E_FAIL;
}
TCHAR temp_[MAX_PATH] = {'\0'};
Axis* axis_ = NULL;
Button* button_ = NULL;
PovDirection* povControl_ = NULL;
switch (control->GetType())
{
case CONTROL_TYPE_AXIS:
_tcscpy_s(name, MAX_PATH, _T(""));
_tcscat_s(name, MAX_PATH, NAME_DINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
axis_ = static_cast<Axis*>(control);
_tcscat_s(name, MAX_PATH, axis_->GetAxisName());
_tcscat_s(name, MAX_PATH, _T(" "));
switch (axis_->GetRangeType())
{
case LG_POSITIVE_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_POSITIVE_RANGE);
break;
case LG_NEGATIVE_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_NEGATIVE_RANGE);
break;
case LG_FULL_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_FULL_RANGE);
break;
default:
_ASSERT(0);
}
break;
case CONTROL_TYPE_BUTTON:
_tcscpy_s(name, MAX_PATH, _T(""));
_tcscat_s(name, MAX_PATH, NAME_DINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
_tcscat_s(name, MAX_PATH, NAME_DINPUT_BUTTON);
_tcscat_s(name, MAX_PATH, _T(" "));
button_ = static_cast<Button*>(control);
_itot_s(button_->GetNumber() + 1, temp_, sizeof(button_->GetNumber()), 10);
_tcscat_s(name, MAX_PATH, temp_);
break;
case CONTROL_TYPE_POV:
_tcscat_s(name, MAX_PATH, NAME_DINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
_tcscat_s(name, MAX_PATH, NAME_DINPUT_POV);
_tcscat_s(name, MAX_PATH, _T(" "));
povControl_= static_cast<PovDirection*>(control);
_itot_s(povControl_->GetPovNumber() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
switch (povControl_->GetDirection())
{
case LG_POV_UP:
_tcscat_s(name, MAX_PATH, NAME_DINPUT_POV_UP);
break;
case LG_POV_DOWN:
_tcscat_s(name, MAX_PATH, NAME_DINPUT_POV_DOWN);
break;
case LG_POV_LEFT:
_tcscat_s(name, MAX_PATH, NAME_DINPUT_POV_LEFT);
break;
case LG_POV_RIGHT:
_tcscat_s(name, MAX_PATH, NAME_DINPUT_POV_RIGHT);
break;
default:
_ASSERT(0);
}
break;
default:
_ASSERT(0);
}
return S_OK;
}
HRESULT ControlsAssignment::GetControlNameXInput(LPTSTR name, Control* control)
{
if (NULL == control)
{
_tcscpy_s(name, MAX_PATH, _T(""));
return E_FAIL;
}
TCHAR temp_[MAX_PATH] = {'\0'};
Axis* axis_ = NULL;
Button* button_ = NULL;
PovDirection* povControl_ = NULL;
switch (control->GetType())
{
case CONTROL_TYPE_AXIS:
_tcscpy_s(name, MAX_PATH, _T(""));
_tcscat_s(name, MAX_PATH, NAME_XINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
axis_ = static_cast<Axis*>(control);
_tcscat_s(name, MAX_PATH, axis_->GetAxisName());
_tcscat_s(name, MAX_PATH, _T(" "));
switch (axis_->GetRangeType())
{
case LG_POSITIVE_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_POSITIVE_RANGE);
break;
case LG_NEGATIVE_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_NEGATIVE_RANGE);
break;
case LG_FULL_RANGE:
_tcscat_s(name, MAX_PATH, SIGN_FULL_RANGE);
break;
default:
_ASSERT(0);
}
break;
case CONTROL_TYPE_BUTTON:
_tcscpy_s(name, MAX_PATH, _T(""));
_tcscat_s(name, MAX_PATH, NAME_XINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON);
_tcscat_s(name, MAX_PATH, _T(" "));
button_ = static_cast<Button*>(control);
switch(button_->GetNumber())
{
case LG_BUTTON_START:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_START);
break;
case LG_BUTTON_BACK:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_BACK);
break;
case LG_BUTTON_LEFT_THUMB:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_LEFT_THUMB);
break;
case LG_BUTTON_RIGHT_THUMB:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_RIGHT_THUMB);
break;
case LG_BUTTON_LEFT_SHOULDER:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_LEFT_SHOULDER);
break;
case LG_BUTTON_RIGHT_SHOULDER:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_RIGHT_SHOULDER);
break;
case LG_BUTTON_A:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_A);
break;
case LG_BUTTON_B:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_B);
break;
case LG_BUTTON_X:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_X);
break;
case LG_BUTTON_Y:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_BUTTON_Y);
break;
default:
_ASSERT(0);
}
break;
case CONTROL_TYPE_POV:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_CONTROLLER);
_tcscat_s(name, MAX_PATH, _T(" "));
_itot_s(control->GetControllerIndex() + 1, temp_, _countof(temp_), 10);
_tcscat_s(name, MAX_PATH, temp_);
_tcscat_s(name, MAX_PATH, _T(" "));
_tcscat_s(name, MAX_PATH, NAME_XINPUT_POV);
_tcscat_s(name, MAX_PATH, _T(" "));
povControl_= static_cast<PovDirection*>(control);
switch (povControl_->GetDirection())
{
case LG_POV_UP:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_POV_UP);
break;
case LG_POV_DOWN:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_POV_DOWN);
break;
case LG_POV_LEFT:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_POV_LEFT);
break;
case LG_POV_RIGHT:
_tcscat_s(name, MAX_PATH, NAME_XINPUT_POV_RIGHT);
break;
default:
_ASSERT(0);
}
break;
default:
_ASSERT(0);
}
return S_OK;
}
/****f* Controls.Assignment.SDK/AssignActionToControl(INT.gameActionID,ControlAssignment&.controlAssignment)
* NAME
* HRESULT AssignActionToControl(INT gameActionID, ControlAssignment&
* controlAssignment) -- Do initial assignment between game actions
* and controls.
* INPUTS
* gameActionID: identification number of the game action.
*
* controlAssignment: assigned control info such as controller number,
* type, control type, axis, button and POV.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* NOTES
* A game will typically read a config file to find out which control
* is assigned to which game action, and then call this function.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::AssignActionToControl(CONST INT gameActionID, CONST ControlAssignment& controlAssignment)
{
if (controlAssignment.controllerIndex < 0 || controlAssignment.controllerIndex >= LG_MAX_NUMBER_SUPPORTED_CONTROLLERS)
return E_FAIL;
// Get corresponding control
Control* control_ = NULL;
if (controlAssignment.controllerType == LG_CONTROLLER_TYPE_NONE)
return E_FAIL;
if (controlAssignment.controllerType == LG_CONTROLLER_TYPE_DINPUT)
control_ = m_controllerDInput[controlAssignment.controllerIndex].GetControl(controlAssignment);
else if (controlAssignment.controllerType == LG_CONTROLLER_TYPE_XINPUT)
control_ = m_controllerXInput[controlAssignment.controllerIndex].GetControl(controlAssignment);
if (NULL == control_)
return E_FAIL;
// set action to control
m_gameActions[gameActionID]->SetControl(control_);
return S_OK;
}
/****f* Controls.Assignment.SDK/GetAssignedActionInfo(ControlAssignment&.controlAssignment,INT.gameActionID)
* NAME
* HRESULT GetAssignedActionInfo(ControlAssignment& controlAssignment,
* INT gameActionID) -- Get game action and corresponding control
* info.
* INPUTS
* gameActionID: identification number of the game action.
*
* controlAssignment: assigned control info such as controller number,
* type, control type, axis, button and POV.
* RETURN VALUE
* S_OK if the wrapper successfully entered the control checking
* state.
* E_FAIL otherwise.
* NOTES
* A game can use the resulting info to write to a config file in
* order to save user controller settings.
* SEE ALSO
* SampleInGameImplementation.cpp to see an example.
******
*/
HRESULT ControlsAssignment::GetAssignedActionInfo(ControlAssignment& controlAssignment, CONST INT gameActionID)
{
controlAssignment.Init();
// Get control corresponding to game action
Control* control_ = GetGameAction(gameActionID)->GetControl();
if (NULL == control_)
return E_FAIL;
Axis* axis_ = NULL;
Button* button_ = NULL;
PovDirection* povDirection_ = NULL;
controlAssignment.controllerIndex = control_->GetControllerIndex();
controlAssignment.controllerType = static_cast<ControllerType>(control_->GetControllerType());
controlAssignment.controlType = static_cast<ControlType>(control_->GetType());
switch(controlAssignment.controlType)
{
case CONTROL_TYPE_AXIS:
axis_ = static_cast<Axis*>(control_);
controlAssignment.axis = axis_->GetAxisID();
controlAssignment.axisRangeType = axis_->GetRangeType();
break;
case CONTROL_TYPE_BUTTON:
button_ = static_cast<Button*>(control_);
controlAssignment.button = button_->GetNumber();
break;
case CONTROL_TYPE_POV:
povDirection_ = static_cast<PovDirection*>(control_);
controlAssignment.povNbr = povDirection_->GetPovNumber();
controlAssignment.povDirection = povDirection_->GetDirection();
break;
default:
_ASSERT(0);
}
return S_OK;
}