void CXInputDevice::Update(bool bFocus) { FUNCTION_PROFILER( GetISystem(),PROFILE_INPUT ); DEBUG_CONTROLLER_RENDER_BUTTON_ACTION; const bool wasConnected = m_connected; const bool connected = g_bConnected[m_deviceNo]; const bool disconnecting = (wasConnected && !connected); UpdateConnectedState(connected); float frameTime = gEnv->pTimer->GetFrameTime(); float now = gEnv->pTimer->GetFrameStartTime().GetSeconds(); if((m_fVibrationTimer && m_fVibrationTimer < now) || g_pInputCVars->i_forcefeedback == 0 || gEnv->pSystem->IsPaused() || frameTime<0.001f) { m_fVibrationTimer = 0; SetVibration(0, 0, 0.0f); } // Force inputs to get sent out when we're disconnecting or // we can get stuck with thumbsticks in a non-neutral state if (disconnecting) { m_forceResendSticks = true; } // interpret input if ((m_connected && bFocus) || disconnecting) { XINPUT_STATE state; memset( &state, 0, sizeof(XINPUT_STATE) ); if ( ERROR_SUCCESS != XInputGetState(m_deviceNo, &state) && !disconnecting) return; if (state.dwPacketNumber != m_state.dwPacketNumber) { SInputEvent event; SInputSymbol* pSymbol = 0; event.deviceIndex = (uint8)m_deviceNo; if (g_pInputCVars->i_xinput_deadzone_handling > 0) { { Vec2 d( state.Gamepad.sThumbLX, state.Gamepad.sThumbLY ); FixDeadzone( d ); state.Gamepad.sThumbLX = d[0]; state.Gamepad.sThumbLY = d[1]; } { Vec2 d( state.Gamepad.sThumbRX, state.Gamepad.sThumbRY ); FixDeadzone( d ); state.Gamepad.sThumbRX = d[0]; state.Gamepad.sThumbRY = d[1]; } } else { const float INV_VALIDRANGE = (1.0f / (INPUT_MAX - m_fDeadZone)); // make the inputs move smoothly out of the deadzone instead of snapping straight to m_fDeadZone float fraction=max((float)abs(state.Gamepad.sThumbLX) - m_fDeadZone, 0.f) * INV_VALIDRANGE; float oldVal=state.Gamepad.sThumbLX; state.Gamepad.sThumbLX = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbLX); fraction = max((float)abs(state.Gamepad.sThumbLY) - m_fDeadZone, 0.f) * INV_VALIDRANGE; oldVal = state.Gamepad.sThumbLY; state.Gamepad.sThumbLY = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbLY); // make the inputs move smoothly out of the deadzone instead of snapping straight to m_fDeadZone fraction=max((float)abs(state.Gamepad.sThumbRX) - m_fDeadZone, 0.f) * INV_VALIDRANGE; oldVal=state.Gamepad.sThumbRX; state.Gamepad.sThumbRX = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbRX); fraction = max((float)abs(state.Gamepad.sThumbRY) - m_fDeadZone, 0.f) * INV_VALIDRANGE; oldVal = state.Gamepad.sThumbRY; state.Gamepad.sThumbRY = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbRY); } // compare new values against cached value and only send out changes as new input WORD buttonsChange = m_state.Gamepad.wButtons ^ state.Gamepad.wButtons; if (buttonsChange) { for (int i = 0; i < 16; ++i) { uint32 id = (1 << i); if (buttonsChange & id && (pSymbol = DevSpecIdToSymbol(id))) { pSymbol->PressEvent((state.Gamepad.wButtons & id) != 0); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); DEBUG_CONTROLLER_LOG_BUTTON_ACTION(pSymbol); } } } // now we have done the digital buttons ... let's do the analog stuff if (m_state.Gamepad.bLeftTrigger != state.Gamepad.bLeftTrigger) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_TRIGGER); pSymbol->ChangeEvent(state.Gamepad.bLeftTrigger / 255.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); DEBUG_CONTROLLER_LOG_BUTTON_ACTION(pSymbol); //--- Check previous and current trigger against threshold for digital press/release event bool bIsPressed=state.Gamepad.bLeftTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false; bool bWasPressed=m_state.Gamepad.bLeftTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false; if(bIsPressed!=bWasPressed) { pSymbol=DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_TRIGGER_BTN); pSymbol->PressEvent(bIsPressed); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); DEBUG_CONTROLLER_LOG_BUTTON_ACTION(pSymbol); } } if (m_state.Gamepad.bRightTrigger != state.Gamepad.bRightTrigger) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_TRIGGER); pSymbol->ChangeEvent(state.Gamepad.bRightTrigger / 255.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); DEBUG_CONTROLLER_LOG_BUTTON_ACTION(pSymbol); //--- Check previous and current trigger against threshold for digital press/release event bool bIsPressed=state.Gamepad.bRightTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD; bool bWasPressed=m_state.Gamepad.bRightTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD; if(bIsPressed!=bWasPressed) { pSymbol=DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_TRIGGER_BTN); pSymbol->PressEvent(bIsPressed); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); DEBUG_CONTROLLER_LOG_BUTTON_ACTION(pSymbol); } } if ((m_state.Gamepad.sThumbLX != state.Gamepad.sThumbLX) || m_forceResendSticks) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_X); if(state.Gamepad.sThumbLX==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbLX + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolLeft = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_LEFT); ProcessAnalogStick(pSymbolLeft, m_state.Gamepad.sThumbLX, state.Gamepad.sThumbLX, -25000); static SInputSymbol* pSymbolRight = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_RIGHT); ProcessAnalogStick(pSymbolRight, m_state.Gamepad.sThumbLX, state.Gamepad.sThumbLX, 25000); } if ((m_state.Gamepad.sThumbLY != state.Gamepad.sThumbLY) || m_forceResendSticks) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_Y); if(state.Gamepad.sThumbLY==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbLY + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolUp = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_UP); ProcessAnalogStick(pSymbolUp, m_state.Gamepad.sThumbLY, state.Gamepad.sThumbLY, 25000); static SInputSymbol* pSymbolDown = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_DOWN); ProcessAnalogStick(pSymbolDown, m_state.Gamepad.sThumbLY, state.Gamepad.sThumbLY, -25000); } if ((m_state.Gamepad.sThumbRX != state.Gamepad.sThumbRX) || m_forceResendSticks) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_X); if(state.Gamepad.sThumbRX==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbRX + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolLeft = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_LEFT); ProcessAnalogStick(pSymbolLeft, m_state.Gamepad.sThumbRX, state.Gamepad.sThumbRX, -25000); static SInputSymbol* pSymbolRight = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_RIGHT); ProcessAnalogStick(pSymbolRight, m_state.Gamepad.sThumbRX, state.Gamepad.sThumbRX, 25000); } if ((m_state.Gamepad.sThumbRY != state.Gamepad.sThumbRY) || m_forceResendSticks) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_Y); if(state.Gamepad.sThumbRY==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbRY + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceType = eIDT_Gamepad; GetIInput().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolUp = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_UP); ProcessAnalogStick(pSymbolUp, m_state.Gamepad.sThumbRY, state.Gamepad.sThumbRY, 25000); static SInputSymbol* pSymbolDown = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_DOWN); ProcessAnalogStick(pSymbolDown, m_state.Gamepad.sThumbRY, state.Gamepad.sThumbRY, -25000); } // update cache m_state = state; m_forceResendSticks = false; } } }
void gkXboxInputDevice::Update(bool bFocus) { float now = gEnv->pTimer->GetCurrTime(); // if((m_fVibrationTimer && m_fVibrationTimer < now) || g_pInputCVars->i_forcefeedback == 0 || gEnv->pSystem->IsPaused()) // { // m_fVibrationTimer = 0; // //SetVibration(0, 0, 0.0f); // } // interpret input if (true || bFocus) { XINPUT_STATE state; memset( &state, 0, sizeof(XINPUT_STATE) ); if ( ERROR_SUCCESS != XInputGetState(m_deviceNo, &state) ) { // disconnected. UpdateConnectedState(false); return; } else { // connected. UpdateConnectedState(true); } if (true || state.dwPacketNumber != m_state.dwPacketNumber) { SInputEvent event; SInputSymbol* pSymbol = 0; event.deviceIndex = (uint8)m_deviceNo; const float INV_VALIDRANGE = (1.0f / (INPUT_MAX - m_fDeadZone)); // make the inputs move smoothly out of the deadzone instead of snapping straight to m_fDeadZone float fraction=max(abs(state.Gamepad.sThumbLX) - m_fDeadZone, 0) * INV_VALIDRANGE; float oldVal=state.Gamepad.sThumbLX; state.Gamepad.sThumbLX = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbLX); fraction = max(abs(state.Gamepad.sThumbLY) - m_fDeadZone, 0) * INV_VALIDRANGE; oldVal = state.Gamepad.sThumbLY; state.Gamepad.sThumbLY = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbLY); // make the inputs move smoothly out of the deadzone instead of snapping straight to m_fDeadZone fraction=max(abs(state.Gamepad.sThumbRX) - m_fDeadZone, 0) * INV_VALIDRANGE; oldVal=state.Gamepad.sThumbRX; state.Gamepad.sThumbRX = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbRX); fraction = max(abs(state.Gamepad.sThumbRY) - m_fDeadZone, 0) * INV_VALIDRANGE; oldVal = state.Gamepad.sThumbRY; state.Gamepad.sThumbRY = fraction * INPUT_MAX * sgn(state.Gamepad.sThumbRY); // compare new values against cached value and only send out changes as new input WORD buttonsChange = m_state.Gamepad.wButtons ^ state.Gamepad.wButtons; if (buttonsChange) { for (int i = 0; i < 16; ++i) { uint32 id = (1 << i); if (buttonsChange & id && (pSymbol = DevSpecIdToSymbol(id))) { pSymbol->PressEvent((state.Gamepad.wButtons & id) != 0); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); } } } // now we have done the digital buttons ... let's do the analog stuff if (m_state.Gamepad.bLeftTrigger != state.Gamepad.bLeftTrigger) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_TRIGGER); pSymbol->ChangeEvent(state.Gamepad.bLeftTrigger / 255.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current trigger against threshold for digital press/release event bool bIsPressed=state.Gamepad.bLeftTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false; bool bWasPressed=m_state.Gamepad.bLeftTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false; if(bIsPressed!=bWasPressed) { pSymbol=DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_TRIGGER_BTN); pSymbol->PressEvent(bIsPressed); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); } } if (m_state.Gamepad.bRightTrigger != state.Gamepad.bRightTrigger) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_TRIGGER); pSymbol->ChangeEvent(state.Gamepad.bRightTrigger / 255.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current trigger against threshold for digital press/release event bool bIsPressed=state.Gamepad.bRightTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD; bool bWasPressed=m_state.Gamepad.bRightTrigger>XINPUT_GAMEPAD_TRIGGER_THRESHOLD; if(bIsPressed!=bWasPressed) { pSymbol=DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_TRIGGER_BTN); pSymbol->PressEvent(bIsPressed); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); } } if (1) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_X); if(state.Gamepad.sThumbLX==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbLX + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolLeft = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_LEFT); ProcessAnalogStick(pSymbolLeft, m_state.Gamepad.sThumbLX, state.Gamepad.sThumbLX, -25000); static SInputSymbol* pSymbolRight = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_RIGHT); ProcessAnalogStick(pSymbolRight, m_state.Gamepad.sThumbLX, state.Gamepad.sThumbLX, 25000); } if (1) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_Y); if(state.Gamepad.sThumbLY==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbLY + 32768.0f) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolUp = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_UP); ProcessAnalogStick(pSymbolUp, m_state.Gamepad.sThumbLY, state.Gamepad.sThumbLY, 25000); static SInputSymbol* pSymbolDown = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_DOWN); ProcessAnalogStick(pSymbolDown, m_state.Gamepad.sThumbLY, state.Gamepad.sThumbLY, -25000); } if (1) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_X); if(state.Gamepad.sThumbRX==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbRX + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolLeft = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_LEFT); ProcessAnalogStick(pSymbolLeft, m_state.Gamepad.sThumbRX, state.Gamepad.sThumbRX, -25000); static SInputSymbol* pSymbolRight = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_RIGHT); ProcessAnalogStick(pSymbolRight, m_state.Gamepad.sThumbRX, state.Gamepad.sThumbRX, 25000); } if (1) { pSymbol = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_Y); if(state.Gamepad.sThumbRY==0.f) pSymbol->ChangeEvent(0.f); else pSymbol->ChangeEvent((state.Gamepad.sThumbRY + 32768) / 32767.5f - 1.0f); pSymbol->AssignTo(event); event.deviceId = eDI_XBox; GetInputManager().PostInputEvent(event); //--- Check previous and current state to generate digital press/release event static SInputSymbol* pSymbolUp = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_UP); ProcessAnalogStick(pSymbolUp, m_state.Gamepad.sThumbRY, state.Gamepad.sThumbRY, 25000); static SInputSymbol* pSymbolDown = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_DOWN); ProcessAnalogStick(pSymbolDown, m_state.Gamepad.sThumbRY, state.Gamepad.sThumbRY, -25000); } // update cache m_state = state; } } }