Apply patch by Lilian Gimenez to support gamepad triggers in input code
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13054 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
ae0cfe90da
commit
a27853a592
@ -47,6 +47,7 @@ irr::core::stringw DeviceConfig::getMappingIdString (const PlayerAction action)
|
||||
const Input::InputType type = m_bindings[action].getType();
|
||||
const int id = m_bindings[action].getId();
|
||||
const Input::AxisDirection dir = m_bindings[action].getDirection();
|
||||
const Input::AxisRange range = m_bindings[action].getRange();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -60,6 +61,8 @@ irr::core::stringw DeviceConfig::getMappingIdString (const PlayerAction action)
|
||||
returnString += id;
|
||||
returnString += "$";
|
||||
returnString += dir;
|
||||
returnString += "$";
|
||||
returnString += range;
|
||||
break;
|
||||
|
||||
case Input::IT_STICKBUTTON:
|
||||
@ -114,9 +117,10 @@ void DeviceConfig::setBinding ( const PlayerAction action,
|
||||
const Input::InputType type,
|
||||
const int id,
|
||||
Input::AxisDirection direction,
|
||||
Input::AxisRange range,
|
||||
wchar_t character)
|
||||
{
|
||||
m_bindings[action].set(type, id, direction, character);
|
||||
m_bindings[action].set(type, id, direction, range, character);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -124,7 +128,7 @@ void DeviceConfig::setBinding ( const PlayerAction action,
|
||||
// Don't call this directly unless you are KeyboardDevice or GamepadDevice
|
||||
bool DeviceConfig::getGameAction(Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value, /* inout */
|
||||
PlayerAction* action /* out */ )
|
||||
{
|
||||
return doGetAction(type, id, value, PA_FIRST_GAME_ACTION, PA_LAST_GAME_ACTION, action);
|
||||
@ -135,7 +139,7 @@ bool DeviceConfig::getGameAction(Input::InputType type,
|
||||
// Don't call this directly unless you are KeyboardDevice or GamepadDevice
|
||||
bool DeviceConfig::getMenuAction(Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value,
|
||||
PlayerAction* action /* out */ )
|
||||
{
|
||||
return doGetAction(type, id, value, PA_FIRST_MENU_ACTION, PA_LAST_MENU_ACTION, action);
|
||||
@ -145,7 +149,7 @@ bool DeviceConfig::getMenuAction(Input::InputType type,
|
||||
|
||||
bool DeviceConfig::doGetAction(Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value, /* inout */
|
||||
const PlayerAction firstActionToCheck,
|
||||
const PlayerAction lastActionToCheck,
|
||||
PlayerAction* action /* out */ )
|
||||
@ -162,13 +166,30 @@ bool DeviceConfig::doGetAction(Input::InputType type,
|
||||
|
||||
if (type == Input::IT_STICKMOTION)
|
||||
{
|
||||
if ( ((m_bindings[n].getDirection() == Input::AD_POSITIVE)
|
||||
&& (value > 0)) ||
|
||||
((m_bindings[n].getDirection() == Input::AD_NEGATIVE)
|
||||
&& (value < 0)) )
|
||||
if(m_bindings[n].getRange() == Input::AR_HALF)
|
||||
{
|
||||
success = true;
|
||||
*action = (PlayerAction)n;
|
||||
if ( ((m_bindings[n].getDirection() == Input::AD_POSITIVE)
|
||||
&& (*value > 0)) ||
|
||||
((m_bindings[n].getDirection() == Input::AD_NEGATIVE)
|
||||
&& (*value < 0)) )
|
||||
{
|
||||
success = true;
|
||||
*action = (PlayerAction)n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ((m_bindings[n].getDirection() == Input::AD_POSITIVE)
|
||||
&& (*value != -Input::MAX_VALUE)) ||
|
||||
((m_bindings[n].getDirection() == Input::AD_NEGATIVE)
|
||||
&& (*value != Input::MAX_VALUE)) )
|
||||
{
|
||||
success = true;
|
||||
*action = (PlayerAction)n;
|
||||
if(m_bindings[n].getDirection() == Input::AD_NEGATIVE)
|
||||
*value = -*value;
|
||||
*value = (*value + Input::MAX_VALUE) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -68,7 +68,7 @@ protected:
|
||||
*/
|
||||
bool doGetAction(Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value, /* inout */
|
||||
const PlayerAction firstActionToCheck,
|
||||
const PlayerAction lastActionToCheck,
|
||||
PlayerAction* action /* out */ );
|
||||
@ -92,6 +92,7 @@ public:
|
||||
const Input::InputType type,
|
||||
const int id,
|
||||
Input::AxisDirection direction = Input::AD_NEUTRAL,
|
||||
Input::AxisRange range = Input::AR_HALF,
|
||||
wchar_t character=0);
|
||||
|
||||
void setPlugged () { m_plugged++; }
|
||||
@ -106,7 +107,7 @@ public:
|
||||
*/
|
||||
bool getGameAction (Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value, /* inout */
|
||||
PlayerAction* action /* out */);
|
||||
|
||||
/**
|
||||
@ -117,7 +118,7 @@ public:
|
||||
*/
|
||||
bool getMenuAction (Input::InputType type,
|
||||
const int id,
|
||||
const int value,
|
||||
int* value,
|
||||
PlayerAction* action /* out */);
|
||||
|
||||
Binding& getBinding (int i) {return m_bindings[i];}
|
||||
|
@ -31,10 +31,11 @@ void Binding::serialize(std::ofstream& stream) const
|
||||
<< "event=\"" << m_type << "\" "
|
||||
<< "character=\"" << m_character << "\" ";
|
||||
|
||||
// Only serialize the direction for stick motions
|
||||
// Only serialize the direction and the range for stick motions
|
||||
if (m_type == Input::IT_STICKMOTION)
|
||||
{
|
||||
stream << "direction=\"" << m_dir << "\" ";
|
||||
stream << "range=\"" << m_range << "\" ";
|
||||
}
|
||||
} // serialize
|
||||
|
||||
@ -44,6 +45,7 @@ bool Binding::deserialize(irr::io::IrrXMLReader* xml)
|
||||
const char *id_string = xml->getAttributeValue("id");
|
||||
const char *event_string = xml->getAttributeValue("event");
|
||||
const char *dir_string = xml->getAttributeValue("direction");
|
||||
const char *range_string = xml->getAttributeValue("range");
|
||||
const char *character = xml->getAttributeValue("character");
|
||||
|
||||
// Proceed only if neccesary tags were found
|
||||
@ -67,7 +69,18 @@ bool Binding::deserialize(irr::io::IrrXMLReader* xml)
|
||||
printf("WARNING: IT_STICKMOTION without direction, ignoring.\n");
|
||||
return false;
|
||||
}
|
||||
m_dir = (Input::AxisDirection)atoi(dir_string);
|
||||
|
||||
// If the action is a stick motion & a range is defined
|
||||
if (range_string == NULL)
|
||||
{
|
||||
m_range = Input::AR_HALF;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_range = (Input::AxisRange)atoi(range_string);
|
||||
}
|
||||
|
||||
m_dir = (Input::AxisDirection)atoi(dir_string);
|
||||
|
||||
} // if m_type!=stickmotion
|
||||
return true;
|
||||
@ -263,7 +276,14 @@ irr::core::stringw Binding::getAsString() const
|
||||
else
|
||||
{
|
||||
//I18N: to appear in input configuration screen, for gamepad axes
|
||||
s = _("Axis %d %s", m_id, (m_dir == Input::AD_NEGATIVE) ? L"-" : L"+");
|
||||
if (m_range == Input::AR_HALF)
|
||||
s = _("Axis %d %s", m_id, (m_dir == Input::AD_NEGATIVE) ? L"-" : L"+");
|
||||
else
|
||||
{
|
||||
irr::core::stringw inv = _("inverted");
|
||||
s = _("Axis %d %s", m_id, (m_dir == Input::AD_NEGATIVE) ? inv : L"");
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case Input::IT_STICKBUTTON:
|
||||
|
@ -36,6 +36,7 @@ private:
|
||||
Input::InputType m_type;
|
||||
int m_id;
|
||||
Input::AxisDirection m_dir;
|
||||
Input::AxisRange m_range;
|
||||
wchar_t m_character;
|
||||
public:
|
||||
/** Returns the type of device this binding is using. */
|
||||
@ -47,12 +48,16 @@ public:
|
||||
/** Returns the direction this binding is using. */
|
||||
Input::AxisDirection getDirection() const {return m_dir;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the range this binding is using. */
|
||||
Input::AxisRange getRange() const {return m_range;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Defines all values of this binding. */
|
||||
void set(Input::InputType type, int id,
|
||||
Input::AxisDirection dir,
|
||||
Input::AxisRange range,
|
||||
wchar_t character)
|
||||
{
|
||||
m_type = type; m_id=id; m_dir=dir; m_character=character;
|
||||
m_type = type; m_id=id; m_dir=dir; m_range=range; m_character=character;
|
||||
} // set
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -322,7 +322,7 @@ InputDevice *DeviceManager::mapGamepadInput( Input::InputType type,
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int value,
|
||||
int *value /* inout */,
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer **player /* out */,
|
||||
PlayerAction *action /* out */)
|
||||
@ -361,14 +361,14 @@ bool DeviceManager::translateInput( Input::InputType type,
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int value,
|
||||
int* value /* inout */,
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer** player /* out */,
|
||||
PlayerAction* action /* out */ )
|
||||
{
|
||||
if (GUIEngine::getCurrentScreen() != NULL)
|
||||
{
|
||||
GUIEngine::getCurrentScreen()->filterInput(type, deviceID, btnID, axisDir, value);
|
||||
GUIEngine::getCurrentScreen()->filterInput(type, deviceID, btnID, axisDir, *value);
|
||||
}
|
||||
|
||||
InputDevice *device = NULL;
|
||||
@ -406,7 +406,7 @@ bool DeviceManager::translateInput( Input::InputType type,
|
||||
|
||||
|
||||
// Return true if input was successfully translated to an action and player
|
||||
if (device != NULL && abs(value) > Input::MAX_VALUE/2)
|
||||
if (device != NULL && abs(*value) > Input::MAX_VALUE/2)
|
||||
{
|
||||
m_latest_used_device = device;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ private:
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int value,
|
||||
int* value /* inout */,
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer **player /* out */,
|
||||
PlayerAction *action /* out */);
|
||||
@ -151,7 +151,7 @@ public:
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int value,
|
||||
int *value /* inout */,
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer** player /* out */,
|
||||
PlayerAction* action /* out */ );
|
||||
|
@ -51,6 +51,12 @@ struct Input
|
||||
AD_NEUTRAL
|
||||
};
|
||||
|
||||
enum AxisRange
|
||||
{
|
||||
AR_HALF,
|
||||
AR_FULL
|
||||
};
|
||||
|
||||
enum InputType
|
||||
{
|
||||
IT_NONE = 0,
|
||||
@ -67,6 +73,7 @@ struct Input
|
||||
int m_device_id;
|
||||
int m_button_id; // or axis ID for gamepads axes
|
||||
int m_axis_direction;
|
||||
int m_axis_range;
|
||||
wchar_t m_character;
|
||||
|
||||
Input()
|
||||
|
@ -162,7 +162,7 @@ void GamePadDevice::resetAxisDirection(const int axis,
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool GamePadDevice::processAndMapInput(Input::InputType type, const int id,
|
||||
const int value,
|
||||
int* value, /* inout */
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer* player,
|
||||
PlayerAction* action /* out */)
|
||||
@ -180,13 +180,13 @@ bool GamePadDevice::processAndMapInput(Input::InputType type, const int id,
|
||||
if (player != NULL)
|
||||
{
|
||||
// going to negative from positive
|
||||
if (value < 0 && m_prevAxisDirections[id] == Input::AD_POSITIVE)
|
||||
if (*value < 0 && m_prevAxisDirections[id] == Input::AD_POSITIVE)
|
||||
{
|
||||
// set positive id to 0
|
||||
resetAxisDirection(id, Input::AD_POSITIVE, player);
|
||||
}
|
||||
// going to positive from negative
|
||||
else if (value > 0 &&
|
||||
else if (*value > 0 &&
|
||||
m_prevAxisDirections[id] == Input::AD_NEGATIVE)
|
||||
{
|
||||
// set negative id to 0
|
||||
@ -194,17 +194,17 @@ bool GamePadDevice::processAndMapInput(Input::InputType type, const int id,
|
||||
}
|
||||
}
|
||||
|
||||
if (value > 0) m_prevAxisDirections[id] = Input::AD_POSITIVE;
|
||||
else if(value < 0) m_prevAxisDirections[id] = Input::AD_NEGATIVE;
|
||||
if (*value > 0) m_prevAxisDirections[id] = Input::AD_POSITIVE;
|
||||
else if(*value < 0) m_prevAxisDirections[id] = Input::AD_NEGATIVE;
|
||||
|
||||
if (!m_axis_ok[id])
|
||||
{
|
||||
if (m_prevAxisValue[id] == -1)
|
||||
{
|
||||
// first value we get from this axis
|
||||
m_prevAxisValue[id] = value;
|
||||
m_prevAxisValue[id] = *value;
|
||||
}
|
||||
else if (m_prevAxisValue[id] != value)
|
||||
else if (m_prevAxisValue[id] != *value)
|
||||
{
|
||||
// second different value we get from this axis, consider it OK
|
||||
m_axis_ok[id] = true;
|
||||
@ -212,7 +212,7 @@ bool GamePadDevice::processAndMapInput(Input::InputType type, const int id,
|
||||
}
|
||||
|
||||
// check if within deadzone
|
||||
if(value > -m_deadzone && value < m_deadzone && player != NULL)
|
||||
if(*value > -m_deadzone && *value < m_deadzone && player != NULL)
|
||||
{
|
||||
// Axis stands still: This is reported once for digital axes and
|
||||
// can be called multipled times for analog ones. Uses the
|
||||
@ -247,7 +247,7 @@ bool GamePadDevice::processAndMapInput(Input::InputType type, const int id,
|
||||
{
|
||||
success = m_configuration->getGameAction(type, id, value, action);
|
||||
}
|
||||
else if (abs(value) > Input::MAX_VALUE/2)
|
||||
else if (abs(*value) > Input::MAX_VALUE/2)
|
||||
{
|
||||
// bindings can only be accessed in game and menu modes
|
||||
assert(mode == InputManager::MENU);
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
* \return Whether the pressed key/button is bound with an action
|
||||
*/
|
||||
bool processAndMapInput(Input::InputType type, const int id,
|
||||
const int value,
|
||||
int* value,
|
||||
InputManager::InputDriverMode mode,
|
||||
StateManager::ActivePlayer* player,
|
||||
PlayerAction* action);
|
||||
|
@ -379,6 +379,8 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
!= m_sensed_input_high_gamepad.end();
|
||||
bool inverse_id_was_high = m_sensed_input_high_gamepad.find(-input_id)
|
||||
!= m_sensed_input_high_gamepad.end();
|
||||
bool id_was_zero = m_sensed_input_zero_gamepad.find(button)
|
||||
!= m_sensed_input_zero_gamepad.end();
|
||||
|
||||
// A stick was pushed far enough (for the first time) to count as
|
||||
// 'triggered' - save the axis (coded with direction in the button
|
||||
@ -388,31 +390,56 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
// to register this as soon as the value is high enough.
|
||||
if (!id_was_high && abs(value) > Input::MAX_VALUE*6.0f/7.0f)
|
||||
{
|
||||
m_sensed_input_high_gamepad.insert(input_id);
|
||||
if(inverse_id_was_high && !id_was_zero) {
|
||||
Input sensed_input;
|
||||
sensed_input.m_type = type;
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
sensed_input.m_axis_direction = (value>=0) ? Input::AD_POSITIVE
|
||||
: Input::AD_NEGATIVE;
|
||||
sensed_input.m_axis_range = Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
|
||||
}
|
||||
else m_sensed_input_high_gamepad.insert(input_id);
|
||||
}
|
||||
else if ( abs(value) < Input::MAX_VALUE/8.0f && id_was_high )
|
||||
else if ( abs(value) < Input::MAX_VALUE/8.0f )
|
||||
{
|
||||
Input sensed_input;
|
||||
sensed_input.m_type = type;
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
sensed_input.m_axis_direction = value>=0 ? Input::AD_POSITIVE
|
||||
: Input::AD_NEGATIVE;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
}
|
||||
else if ( abs(value) < Input::MAX_VALUE/8.0f && inverse_id_was_high )
|
||||
{
|
||||
Input sensed_input;
|
||||
sensed_input.m_type = type;
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
// Since the inverse direction was high (i.e. stick went from
|
||||
// +30000 to -100), we have to inverse the sign
|
||||
sensed_input.m_axis_direction = value>=0 ? Input::AD_NEGATIVE
|
||||
: Input::AD_POSITIVE;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
if( id_was_high )
|
||||
{
|
||||
Input sensed_input;
|
||||
sensed_input.m_type = type;
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
sensed_input.m_axis_direction = (value>=0) == id_was_zero
|
||||
? Input::AD_POSITIVE
|
||||
: Input::AD_NEGATIVE;
|
||||
sensed_input.m_axis_range = id_was_zero ? Input::AR_HALF
|
||||
: Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
}
|
||||
else if( inverse_id_was_high )
|
||||
{
|
||||
Input sensed_input;
|
||||
sensed_input.m_type = type;
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
// Since the inverse direction was high (i.e. stick went from
|
||||
// +30000 to -100), we have to inverse the sign
|
||||
sensed_input.m_axis_direction = (value>=0) == id_was_zero
|
||||
? Input::AD_NEGATIVE
|
||||
: Input::AD_POSITIVE;
|
||||
sensed_input.m_axis_range = id_was_zero ? Input::AR_HALF
|
||||
: Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sensed_input_zero_gamepad.insert(button);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -485,7 +512,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
|
||||
PlayerAction action;
|
||||
bool action_found = m_device_manager->translateInput(type, deviceID,
|
||||
button, axisDirection,
|
||||
value, m_mode,
|
||||
&value, m_mode,
|
||||
&player, &action);
|
||||
|
||||
// in menus, some keyboard keys are standard (before each player selected
|
||||
@ -968,6 +995,7 @@ void InputManager::setMode(InputDriverMode new_mode)
|
||||
|
||||
//irr_driver->showPointer();
|
||||
m_sensed_input_high_gamepad.clear();
|
||||
m_sensed_input_zero_gamepad.clear();
|
||||
m_sensed_input_high_kbd.clear();
|
||||
|
||||
// The order is deliberate just in case someone starts
|
||||
|
@ -57,6 +57,7 @@ private:
|
||||
DeviceManager *m_device_manager;
|
||||
std::set<int> m_sensed_input_high_gamepad;
|
||||
std::set<int> m_sensed_input_high_kbd;
|
||||
std::set<int> m_sensed_input_zero_gamepad;
|
||||
|
||||
InputDriverMode m_mode;
|
||||
|
||||
|
@ -257,6 +257,7 @@ void OptionsScreenInput::filterInput(Input::InputType type,
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int axisRange,
|
||||
int value)
|
||||
{
|
||||
if (type == Input::IT_STICKMOTION || type == Input::IT_STICKBUTTON)
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
int deviceID,
|
||||
int btnID,
|
||||
int axisDir,
|
||||
int axisRange,
|
||||
int value);
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
|
@ -350,6 +350,7 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
KeyboardConfig* keyboard = (KeyboardConfig*)m_config;
|
||||
keyboard->setBinding(binding_to_set, Input::IT_KEYBOARD,
|
||||
sensed_input.m_button_id, Input::AD_NEUTRAL,
|
||||
Input::AR_HALF,
|
||||
sensed_input.m_character);
|
||||
|
||||
// refresh display
|
||||
@ -387,7 +388,8 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
GamepadConfig* config = (GamepadConfig*)m_config;
|
||||
config->setBinding(binding_to_set, sensed_input.m_type,
|
||||
sensed_input.m_button_id,
|
||||
(Input::AxisDirection)sensed_input.m_axis_direction);
|
||||
(Input::AxisDirection)sensed_input.m_axis_direction,
|
||||
(Input::AxisRange)sensed_input.m_axis_range);
|
||||
|
||||
// refresh display
|
||||
updateInputButtons();
|
||||
|
Loading…
Reference in New Issue
Block a user