Exemplo n.º 1
0
/** @brief Check for reportable presses. */
void InputFilter::CheckButtonChange( ButtonState &bs, DeviceInput di, const RageTimer &now )
{
    if( bs.m_BeingHeld == bs.m_bLastReportedHeld )
        return;

    /* If the last IET_FIRST_PRESS or IET_RELEASE event was sent too recently,
     * wait a while before sending it. */
    if( now - bs.m_LastReportTime < g_fInputDebounceTime )
        return;

    bs.m_LastReportTime = now;
    bs.m_bLastReportedHeld = bs.m_BeingHeld;
    bs.m_fSecsHeld = 0;
    bs.m_LastInputTime = bs.m_BeingHeldTime;

    di.ts = bs.m_BeingHeldTime;
    if( !bs.m_bLastReportedHeld )
        di.level = 0;

    MakeButtonStateList( g_CurrentState );
    ReportButtonChange( di, bs.m_bLastReportedHeld? IET_FIRST_PRESS:IET_RELEASE );

    if( !bs.m_bLastReportedHeld )
        g_DisableRepeat.erase( di );
}
Exemplo n.º 2
0
void InputFilter::ButtonPressed( const DeviceInput &di )
{
    LockMut(*queuemutex);

    if( di.ts.IsZero() )
        LOG->Warn( "InputFilter::ButtonPressed: zero timestamp is invalid" );

    ASSERT_M( di.device < NUM_InputDevice, ssprintf("Invalid device %i", di.device) );
    ASSERT_M( di.button < NUM_DeviceButton, ssprintf("Invalid button %i", di.button) );

    ButtonState &bs = GetButtonState( di );

    // Flush any delayed input, like Update() (in case Update() isn't being called).
    RageTimer now;
    CheckButtonChange( bs, di, now );

    bs.m_DeviceInput = di;

    bool Down = di.bDown;
    if( bs.m_BeingHeld != Down )
    {
        bs.m_BeingHeld = Down;
        bs.m_BeingHeldTime = di.ts;
    }

    // Try to report presses immediately.
    MakeButtonStateList( g_CurrentState );
    CheckButtonChange( bs, di, now );
}
Exemplo n.º 3
0
/** @brief Check for reportable presses. */
void InputFilter::CheckButtonChange( ButtonState &bs, DeviceInput di, const RageTimer &now )
{
	if( bs.m_BeingHeld == bs.m_bLastReportedHeld )
		return;
	
	GameInput gi;

	/* Possibly apply debounce,
	 * If the input was coin, possibly apply distinct coin debounce in the else below. */
	if (! INPUTMAPPER->DeviceToGame(di, gi) || gi.button != GAME_BUTTON_COIN )
	{
		/* If the last IET_FIRST_PRESS or IET_RELEASE event was sent too recently,
		 * wait a while before sending it. */
		if( now - bs.m_LastReportTime < g_fInputDebounceTime )
		{
			return;
		}
	} else {
		if( now - bs.m_LastReportTime < PREFSMAN->m_fDebounceCoinInputTime )
		{
			return;
		}
	}
	
	bs.m_LastReportTime = now;
	bs.m_bLastReportedHeld = bs.m_BeingHeld;
	bs.m_fSecsHeld = 0;
	bs.m_LastInputTime = bs.m_BeingHeldTime;

	di.ts = bs.m_BeingHeldTime;
	if( !bs.m_bLastReportedHeld )
		di.level = 0;

	MakeButtonStateList( g_CurrentState );
	ReportButtonChange( di, bs.m_bLastReportedHeld? IET_FIRST_PRESS:IET_RELEASE );

	if( !bs.m_bLastReportedHeld )
		g_DisableRepeat.erase( di );
}
Exemplo n.º 4
0
void InputFilter::ButtonPressed( const DeviceInput &di )
{
	LockMut(*queuemutex);

	if( di.ts.IsZero() )
		LOG->Warn( "InputFilter::ButtonPressed: zero timestamp is invalid" );

	// Filter out input that is beyond the range of the current system.
	if(di.device >= NUM_InputDevice)
	{
		LOG->Trace("InputFilter::ButtonPressed: Invalid device %i", di.device);
		return;
	}
	if(di.button >= NUM_DeviceButton)
	{
		LOG->Trace("InputFilter::ButtonPressed: Invalid button %i", di.button);
		return;
	}

	ButtonState &bs = GetButtonState( di );

	// Flush any delayed input, like Update() (in case Update() isn't being called).
	RageTimer now;
	CheckButtonChange( bs, di, now );

	bs.m_DeviceInput = di;

	bool Down = di.bDown;
	if( bs.m_BeingHeld != Down )
	{
		bs.m_BeingHeld = Down;
		bs.m_BeingHeldTime = di.ts;
	}

	// Try to report presses immediately.
	MakeButtonStateList( g_CurrentState );
	CheckButtonChange( bs, di, now );
}
Exemplo n.º 5
0
void InputFilter::Update( float fDeltaTime )
{
    RageTimer now;

    INPUTMAN->Update();

    /* Make sure that nothing gets inserted while we do this, to prevent things
     * like "key pressed, key release, key repeat". */
    LockMut(*queuemutex);

    DeviceInput di( InputDevice_Invalid, DeviceButton_Invalid, 1.0f, now );

    MakeButtonStateList( g_CurrentState );

    vector<ButtonStateMap::iterator> ButtonsToErase;

    FOREACHM( DeviceButtonPair, ButtonState, g_ButtonStates, b )
    {
        di.device = b->first.device;
        di.button = b->first.button;
        ButtonState &bs = b->second;

        // Generate IET_FIRST_PRESS and IET_RELEASE events that were delayed.
        CheckButtonChange( bs, di, now );

        // Generate IET_REPEAT events.
        if( !bs.m_bLastReportedHeld )
        {
            // If the key isn't pressed, and hasn't been pressed for a while
            // (so debouncing isn't interested in it), purge the entry.
            if( now - bs.m_LastReportTime > g_fInputDebounceTime &&
                    bs.m_DeviceInput.level == 0.0f )
                ButtonsToErase.push_back( b );
            continue;
        }

        // If repeats are disabled for this button, skip.
        if( g_DisableRepeat.find(di) != g_DisableRepeat.end() )
            continue;

        const float fOldHoldTime = bs.m_fSecsHeld;
        bs.m_fSecsHeld += fDeltaTime;
        const float fNewHoldTime = bs.m_fSecsHeld;

        if( fNewHoldTime <= g_fTimeBeforeRepeats )
            continue;

        float fRepeatTime;
        if( fOldHoldTime < g_fTimeBeforeRepeats )
        {
            fRepeatTime = g_fTimeBeforeRepeats;
        }
        else
        {
            float fAdjustedOldHoldTime = fOldHoldTime - g_fTimeBeforeRepeats;
            float fAdjustedNewHoldTime = fNewHoldTime - g_fTimeBeforeRepeats;
            if( int(fAdjustedOldHoldTime/g_fTimeBetweenRepeats) == int(fAdjustedNewHoldTime/g_fTimeBetweenRepeats) )
                continue;
            fRepeatTime = ftruncf( fNewHoldTime, g_fTimeBetweenRepeats );
        }

        /* Set the timestamp to the exact time of the repeat. This way, as long
         * as tab/` aren't being used, the timestamp will always increase steadily
         * during repeats. */
        di.ts = bs.m_LastInputTime + fRepeatTime;

        ReportButtonChange( di, IET_REPEAT );
    }