void InputFilter::ButtonPressed( DeviceInput di, bool Down ) { LockMut(*queuemutex); if( di.ts.IsZero() ) LOG->Warn( "InputFilter::ButtonPressed: zero timestamp is invalid" ); if( di.device >= NUM_INPUT_DEVICES ) { LOG->Warn( "Invalid device %i,%i", di.device, NUM_INPUT_DEVICES ); return; } if( di.button >= GetNumDeviceButtons(di.device) ) { LOG->Warn( "Invalid button %i,%i", di.button, GetNumDeviceButtons(di.device) ); return; } ButtonState &bs = m_ButtonState[di.device][di.button]; RageTimer now; CheckButtonChange( bs, di, now ); if( bs.m_BeingHeld != Down ) { bs.m_BeingHeld = Down; bs.m_BeingHeldTime = di.ts; } /* Try to report presses immediately. */ CheckButtonChange( bs, di, now ); }
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 ); }
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 ); }
void InputFilter::Update(float fDeltaTime) { RageTimer now; INPUTMAN->Update( fDeltaTime ); /* Make sure that nothing gets inserted while we do this, to prevent * things like "key pressed, key release, key repeat". */ LockMut(*queuemutex); // Don't reconstruct "di" inside the loop. This line alone is // taking 4% of the CPU on a P3-666. DeviceInput di( (InputDevice)0,0,1.0f,now); FOREACH_InputDevice( d ) { di.device = d; for( int b=0; b < GetNumDeviceButtons(d); b++ ) // foreach button { ButtonState &bs = m_ButtonState[d][b]; di.button = b; CheckButtonChange( bs, di, now ); /* Generate IET_LEVEL_CHANGED events. */ /* EXPERIMENTAL: this doesn't seem to be used at all, so why bother? * Let's see if any weird bugs pop up as a result. * if( bs.m_LastLevel != bs.m_Level ) { queue.push_back( InputEvent(di,IET_LEVEL_CHANGED) ); bs.m_LastLevel = bs.m_Level; } */ /* Generate IET_FAST_REPEAT and IET_SLOW_REPEAT events. */ if( !bs.m_LastReportedHeld ) continue; const float fOldHoldTime = bs.m_fSecsHeld; bs.m_fSecsHeld += fDeltaTime; const float fNewHoldTime = bs.m_fSecsHeld; if( fNewHoldTime <= g_fTimeBeforeSlow ) continue; float fTimeBetweenRepeats; InputEventType iet; if( fOldHoldTime > g_fTimeBeforeSlow ) { if( fOldHoldTime > g_fTimeBeforeFast ) { fTimeBetweenRepeats = g_fTimeBetweenFast; iet = IET_FAST_REPEAT; } else { fTimeBetweenRepeats = g_fTimeBetweenSlow; iet = IET_SLOW_REPEAT; } if( int(fOldHoldTime/fTimeBetweenRepeats) != int(fNewHoldTime/fTimeBetweenRepeats) ) { queue.push_back( InputEvent(di,iet) ); } } } } }
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 ); }