bool GamePadDevice::processAndMapInput(Input::InputType type, const int id, InputManager::InputDriverMode mode, PlayerAction* action /* out */, int* value /* inout */ ) { if (!m_configuration->isEnabled()) return false; // A digital input value is 32767 or -32768 (which then triggers // time-full-steer to be used to adjust actual steering values. // To prevent this delay for analog gamesticks, make sure that // 32767/-32768 are never used. if(m_configuration->isAnalog()) { if(*value==32767) *value = 32766; else if(*value==-32768) *value = -32767; } // Desensitizing means to map an input in the range x in [0,1] to // x^2. This results in changes close to 0 to have less impact // (less sensitive). if(m_configuration->desensitize()) { // x/32767 is in [-1,1], (x/32767)^2 is in [0,1]. Take care of the // sign and map this back to [0,32767] by multiplying by 32767. // Which all in all results in: *value = int( (*value / 32767.0f) * fabsf(float(*value)) ); } bool success = false; if(m_prev_axis_directions == NULL) return false; // device not open if (type == Input::IT_STICKMOTION) { // this gamepad doesn't even have that many axes if (id >= m_configuration->getNumberOfAxes()) return false; if (getPlayer()) { // going to negative from positive if (*value < 0 && m_prev_axis_directions[id] == Input::AD_POSITIVE) { // set positive id to 0 resetAxisDirection(id, Input::AD_POSITIVE); } // going to positive from negative else if (*value > 0 && m_prev_axis_directions[id] == Input::AD_NEGATIVE) { // set negative id to 0 resetAxisDirection(id, Input::AD_NEGATIVE); } } if (*value > 0) m_prev_axis_directions[id] = Input::AD_POSITIVE; else if(*value < 0) m_prev_axis_directions[id] = Input::AD_NEGATIVE; if (!m_axis_ok[id]) { if (m_prev_axis_value[id] == -1) { // first value we get from this axis m_prev_axis_value[id] = *value; } else if (m_prev_axis_value[id] != *value) { // second different value we get from this axis, consider it OK m_axis_ok[id] = true; } } int dz = static_cast<GamepadConfig*>(m_configuration)->getDeadzone(); // check if within deadzone if(*value > -dz && *value < dz && getPlayer()) { // Axis stands still: This is reported once for digital axes and // can be called multipled times for analog ones. Uses the // previous direction in which the id was triggered to // determine which one has to be brought into the released // state. This allows us to regard two directions of an id // as completely independent input variants (as if they where // two buttons). if(m_prev_axis_directions[id] == Input::AD_NEGATIVE) { // set negative id to 0 resetAxisDirection(id, Input::AD_NEGATIVE); } else if(m_prev_axis_directions[id] == Input::AD_POSITIVE) { // set positive id to 0 resetAxisDirection(id, Input::AD_POSITIVE); } m_prev_axis_directions[id] = Input::AD_NEUTRAL; return false; } // If axis did not send proper values yet, ignore it. if (!m_axis_ok[id]) return false; } if (mode == InputManager::INGAME) { success = m_configuration->getGameAction(type, id, value, action); } else if (abs(*value) > Input::MAX_VALUE/2) { // bindings can only be accessed in game and menu modes assert(mode == InputManager::MENU); success = m_configuration->getMenuAction(type, id, value, action); } return success; } // processAndMapInput
bool GamePadDevice::processAndMapInput(Input::InputType type, const int id, const int value, InputManager::InputDriverMode mode, StateManager::ActivePlayer* player, PlayerAction* action /* out */) { if (!m_configuration->isEnabled()) return false; bool success = false; if(m_prevAxisDirections == NULL) return false; // device not open if (type == Input::IT_STICKMOTION) { if (id >= m_axis_count && id != Input::HAT_H_ID && id != Input::HAT_V_ID) return false; // this gamepad doesn't even have that many axes if (player != NULL) { // going to negative from 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 && m_prevAxisDirections[id] == Input::AD_NEGATIVE) { // set negative id to 0 resetAxisDirection(id, Input::AD_NEGATIVE, player); } } 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; } else if (m_prevAxisValue[id] != value) { // second different value we get from this axis, consider it OK m_axis_ok[id] = true; } } // check if within deadzone 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 // previous direction in which the id was triggered to // determine which one has to be brought into the released // state. This allows us to regard two directions of an id // as completely independent input variants (as if they where // two buttons). if(m_prevAxisDirections[id] == Input::AD_NEGATIVE) { // set negative id to 0 resetAxisDirection(id, Input::AD_NEGATIVE, player); } else if(m_prevAxisDirections[id] == Input::AD_POSITIVE) { // set positive id to 0 resetAxisDirection(id, Input::AD_POSITIVE, player); } m_prevAxisDirections[id] = Input::AD_NEUTRAL; return false; } // If axis did not send proper values yet, ignore it. if (!m_axis_ok[id]) return false; } if (m_configuration != NULL) { if (mode == InputManager::INGAME) { success = m_configuration->getGameAction(type, id, value, action); } else if (abs(value) > Input::MAX_VALUE/2) { // bindings can only be accessed in game and menu modes assert(mode == InputManager::MENU); success = m_configuration->getMenuAction(type, id, value, action); } } else { fprintf(stderr, "processAndMapInput() called on improperly " "initialized GamePadDevice\n"); abort(); } return success; } // processAndMapInput