Exemple #1
0
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
Exemple #2
0
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