Ejemplo n.º 1
0
void CSDLPad::HandleAxisEvent(const SDL_JoyAxisEvent& axisEvt)
{
	if (!m_connected) return;

	SInputSymbol *pSymbol = NULL;
	SInputEvent inputEvt;
	//CryLogAlways("CSDLPad - AXIS requested(%d) %d on Gamepad [%d]", axisEvt.axis, axisEvt.value, m_deviceNo);
	const int id = SDL_GAMEPAD_AXIS(axisEvt.axis);
	pSymbol = DevSpecIdToSymbol(id);
	if (pSymbol)
	{
		switch(id)
		{
			case SDL_GAMEPAD_LEFT_THUMB_X:
			case SDL_GAMEPAD_RIGHT_THUMB_X: 
				pSymbol->value = DeadZoneFilter(axisEvt.value);
				break;
			case SDL_GAMEPAD_LEFT_THUMB_Y:
			case SDL_GAMEPAD_RIGHT_THUMB_Y: 
				// Input system seems to expect Y input to be inverted relative to SDL values
				pSymbol->value = -1.0f * DeadZoneFilter(axisEvt.value);
				break;
			case SDL_GAMEPAD_RIGHT_TRIGGER_DUPE:
				// ignore
				break;
			case SDL_GAMEPAD_LEFT_TRIGGER_DUPE:
				// ignore
				break;
			case SDL_GAMEPAD_RIGHT_TRIGGER:
			case SDL_GAMEPAD_LEFT_TRIGGER:
				if (axisEvt.value < 0)
					pSymbol->value = -1.0f * ((float)(SDL_GAMEPAD_AXIS_MIN - axisEvt.value) / ((float) SDL_GAMEPAD_AXIS_MAX * 2.0f));
				else
					pSymbol->value = 0.5f + ((float)axisEvt.value / ((float) SDL_GAMEPAD_AXIS_MAX * 2.0f));
				
				if (pSymbol->value > -1.0f)
				{
					SInputSymbol *btnSymbol = DevSpecIdToSymbol(id == SDL_GAMEPAD_LEFT_TRIGGER ? SDL_GAMEPAD_LEFT_TRIGGER_BTN : SDL_GAMEPAD_RIGHT_TRIGGER_BTN);
					if (btnSymbol)
					{
						if (pSymbol->value > SDL_GAMEPAD_TRIGGER_MIN_VAL_FOR_BUTTON)
							btnSymbol->state = eIS_Pressed; 
						else
							btnSymbol->state = eIS_Released;

						btnSymbol->AssignTo(inputEvt);
						GetLinuxInput().PostInputEvent(inputEvt);
					}
				}
				break;
			default:
				gEnv->pLog->LogError("CSDLPad - Unknown AXIS requested(%d) on Gamepad [%d]", axisEvt.axis, m_deviceNo);
				return;
		}

		pSymbol->state = eIS_Changed;
		pSymbol->AssignTo(inputEvt);
		GetLinuxInput().PostInputEvent(inputEvt);
	}
}
Ejemplo n.º 2
0
void CXInputDevice::ClearAnalogKeyState(TInputSymbols& clearedSymbols)
{
	if (m_state.Gamepad.sThumbLX!=0 || m_state.Gamepad.sThumbLY!=0 || m_state.Gamepad.sThumbRX!=0 || m_state.Gamepad.sThumbRY!=0)
	{
		// Only resend if the sticks are actually active. If they aren't then active then sending a resendsticks causes pad inputs to be sent through even if you aren't using the pad - which messes with the UI on PC.
		m_forceResendSticks = true;
	}

	// Reset internal state and decrement packet number so updated again immediately
	// This will force-send the current state of all analog keys on next update
	m_state.Gamepad.sThumbLX = 0;
	m_state.Gamepad.sThumbLY = 0;
	m_state.Gamepad.sThumbRX = 0;
	m_state.Gamepad.sThumbRY = 0;
	m_state.Gamepad.bLeftTrigger = 0;
	m_state.Gamepad.bRightTrigger = 0;
	m_state.dwPacketNumber--;

	//remove the symbols cleared above from the hold list
	static SInputSymbol* pSymbolUpL = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_UP);
	static SInputSymbol* pSymbolDownL = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_DOWN);
	static SInputSymbol* pSymbolLeftL = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_LEFT);
	static SInputSymbol* pSymbolRightL = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_THUMB_RIGHT);

	static SInputSymbol* pSymbolUpR = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_UP);
	static SInputSymbol* pSymbolDownR = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_DOWN);
	static SInputSymbol* pSymbolLeftR = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_LEFT);
	static SInputSymbol* pSymbolRightR = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_THUMB_RIGHT);

	static SInputSymbol* pSymbolTrgBtnL = DevSpecIdToSymbol(_XINPUT_GAMEPAD_LEFT_TRIGGER_BTN);
	static SInputSymbol* pSymbolTrgBtnR = DevSpecIdToSymbol(_XINPUT_GAMEPAD_RIGHT_TRIGGER_BTN);

	clearedSymbols.reserve(10);

	clearedSymbols.push_back(pSymbolUpL);
	clearedSymbols.push_back(pSymbolDownL);
	clearedSymbols.push_back(pSymbolLeftL);
	clearedSymbols.push_back(pSymbolRightL);
	clearedSymbols.push_back(pSymbolUpR);
	clearedSymbols.push_back(pSymbolDownR);
	clearedSymbols.push_back(pSymbolLeftR);
	clearedSymbols.push_back(pSymbolRightR);
	clearedSymbols.push_back(pSymbolTrgBtnL);
	clearedSymbols.push_back(pSymbolTrgBtnR);
}
Ejemplo n.º 3
0
void CSDLPad::HandleButtonEvent(const SDL_JoyButtonEvent& btEvt)
{
	if (!m_connected) return;

	//CryLogAlways("BTEVENT EVT: bt:%d %s",btEvt.button, (btEvt.state & SDL_PRESSED) ? "PRESSED" : "RELEASED" );
	SInputSymbol *pSymbol = DevSpecIdToSymbol(btEvt.button);
	if (pSymbol)
	{
		SInputEvent inputEvt;
		const EInputState currState = (btEvt.state & SDL_PRESSED) ? eIS_Pressed : eIS_Released;
		//CryLogAlways("BTEVENT SYM: name: %s state:%d=>%d", pSymbol->name.c_str(), int(pSymbol->state), int(currState));
		bool isPost = false;
		switch (btEvt.button)
		{
			// Special handling so they act more like the hat events; events only triggered on 
			// initial press and release
			case SDL_GAMEPAD_LEFT_THUMB_UP:
			case SDL_GAMEPAD_LEFT_THUMB_DOWN:
			case SDL_GAMEPAD_LEFT_THUMB_LEFT:
			case SDL_GAMEPAD_LEFT_THUMB_RIGHT:
				isPost = (pSymbol->state == eIS_Unknown)
					|| (currState == eIS_Pressed && (pSymbol->state == eIS_Released))
					|| (currState == eIS_Released && (pSymbol->state == eIS_Pressed || pSymbol->state == eIS_Down));
				break;
			default:
				isPost = true;
				break;
		}
		if (isPost)
		{
			pSymbol->state = currState;
			pSymbol->AssignTo(inputEvt);
			GetLinuxInput().PostInputEvent(inputEvt);
		}
	}
	else
	{
		switch (btEvt.button)
		{
			// Ignore buttons that are known to be unmapped and we intentionally don't handle
			case SDL_GAMEPAD_BUTTON_LEFT_TRIGGER_DUPE:
			case SDL_GAMEPAD_BUTTON_RIGHT_TRIGGER_DUPE:
				break;
			default:
				gEnv->pLog->LogError("CSDLPad - Gamepad [%d] received unmapped button event %d", m_deviceNo, btEvt.button);
				break;
		}
	}
}
Ejemplo n.º 4
0
void CMouse::Update(bool bFocus)
{
	FUNCTION_PROFILER( GetISystem(),PROFILE_INPUT );
	HRESULT hr;
	
	if (!GetDirectInputDevice()) 
		return;

	m_deltas.zero();
	m_mouseWheel = 0;

	SInputSymbol* pSymbol = 0;
	EInputState newState;

	if (g_pInputCVars->i_mouse_buffered)
	{
		//memcpy(m_oldEvents, m_Events, sizeof(m_Events));
		//memset(m_Events,0,sizeof(m_Events));

		DIDEVICEOBJECTDATA Events[200];
		// // Buffer mouse input.
		DWORD nElements = 200;
		while (nElements > 0)
		{
			hr = GetDirectInputDevice()->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), Events, &nElements, 0);

			if (FAILED(hr) && Acquire())
			{
				// try again
				hr = GetDirectInputDevice()->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), Events, &nElements, 0);
			}
			
			if (FAILED(hr))
				return;

			if (nElements > 0)
			{
				for (int i = 0; i < (int)nElements; i++)
				{
					pSymbol = DevSpecIdToSymbol(Events[i].dwOfs);
					if (pSymbol)
					{
						// marcok: should actually process axis events here as` well,
						// but I'm not sure if the game can handle multiple move events

						if (pSymbol->type == SInputSymbol::Button)
						{
							if (Events[i].dwData&0x80)
							{
								pSymbol->state = eIS_Pressed;
								pSymbol->value = 1.0;
							}
							else
							{
								pSymbol->state = eIS_Released;
								pSymbol->value = 0.0;
							}
							PostEvent(pSymbol);
						}
					}
					switch (Events[i].dwOfs) 
					{
					case DIMOFS_X: 
						m_deltas.x += float((int)Events[i].dwData);
						break;
					case DIMOFS_Y: 
						m_deltas.y += float((int)Events[i].dwData);
						break; 
					case DIMOFS_Z:
						m_mouseWheel += float((int)Events[i].dwData);
						break;
					}
				}
			}
		}
	}
	else
	{
		// Not buffered.
		DIMOUSESTATE2 dims;
		memset (&dims, 0, sizeof(dims));

		hr = GetDirectInputDevice()->GetDeviceState(sizeof(DIMOUSESTATE2), &dims);	

		if (FAILED(hr) && Acquire())
		{
			// try again
			hr = GetDirectInputDevice()->GetDeviceState(sizeof(DIMOUSESTATE2), &dims);
		}

		if (SUCCEEDED(hr))
		{
			m_deltas.set((float)dims.lX, (float)dims.lY);
			m_mouseWheel = (float)dims.lZ;
		
			for (int i=0; i<8; ++i)
			{
				newState = (dims.rgbButtons[i]&0x80) ? eIS_Pressed : eIS_Released;
				PostOnlyIfChanged(Symbol[i], newState);
			}
		}		
	}

	m_deltas *= g_pInputCVars->i_mouse_sensitivity;

	//marcok: here the raw input already gets cooked a bit ... should be moved
	float mouseaccel = g_pInputCVars->i_mouse_accel;

	if (mouseaccel>0.0f)
	{
		m_deltas.x = m_deltas.x * (float)fabs(m_deltas.x * mouseaccel);
		m_deltas.y = m_deltas.y * (float)fabs(m_deltas.y * mouseaccel);

		CapDeltas(g_pInputCVars->i_mouse_accel_max);
	}

	SmoothDeltas(g_pInputCVars->i_mouse_smooth);

	const bool hasDeltaChanged = !(fcmp(m_deltas.x,m_oldDeltas.x) && fcmp(m_deltas.y,m_oldDeltas.y)); 
	m_oldDeltas = m_deltas; //this needs to happen always. We want to keep the attribute always valid

	//mouse wheel - use custom code instead of PostOnlyWhenChanged because we want the mouseWheel value
	if(m_mouseWheel > 0.0f)
	{
		SInputSymbol* pSymbol = Symbol[eKI_MouseWheelUp-KI_MOUSE_BASE];
		pSymbol->value = m_mouseWheel;
		pSymbol->state = eIS_Pressed;
		PostEvent(pSymbol);
	}
	else if (m_mouseWheel < 0.0f)
	{
		SInputSymbol* pSymbol = Symbol[eKI_MouseWheelDown-KI_MOUSE_BASE];
		pSymbol->value = m_mouseWheel;
		pSymbol->state = eIS_Pressed;
		PostEvent(pSymbol);		
	}
	else
	{
		SInputSymbol* pSymbol = Symbol[eKI_MouseWheelUp-KI_MOUSE_BASE];
		if(pSymbol->state != eIS_Released)
		{
			pSymbol->value = 0.0f;
			pSymbol->state = eIS_Released;
			PostEvent(pSymbol);	
		}

		SInputSymbol* pSymbol2 = Symbol[eKI_MouseWheelDown-KI_MOUSE_BASE];
		if(pSymbol2->state != eIS_Released)
		{
			pSymbol2->value = 0.0f;
			pSymbol2->state = eIS_Released;
			PostEvent(pSymbol2);	
		}
	}
	
	// mouse movements
	if (m_deltas.GetLength2()>0.0f || hasDeltaChanged || m_mouseWheel)
	{
		pSymbol = Symbol[eKI_MouseX-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_deltas.x;
		PostEvent(pSymbol);

		pSymbol = Symbol[eKI_MouseY-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_deltas.y;
		PostEvent(pSymbol);

		pSymbol = Symbol[eKI_MouseZ-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_mouseWheel;
		PostEvent(pSymbol);
	}

	//////////////////////////////////////////////////////////////////////////
	float inertia = g_pInputCVars->i_mouse_inertia;

	// mouse inertia
	if (inertia>0) 
	{
		float dt = gEnv->pTimer->GetFrameTime();
		if (dt>0.1f) dt=0.1f;
		m_deltas = (m_deltasInertia += (m_deltas-m_deltasInertia)*inertia*dt);
	}
}
Ejemplo n.º 5
0
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;
		}
	}
}
Ejemplo n.º 6
0
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;
		}
	}
}
Ejemplo n.º 7
0
void CSDLKeyboard::Update(bool focus)
{
    SDL_Event eventList[KEYBOARD_MAX_PEEP];
    
    int nEvents;
    unsigned type = 0;
#if !defined(_RELEASE)
    // Stop SDL2 from generating text input event when pressing the console
    // key to hide/show the in-game console
    bool didPressTild = false;
#endif
    SInputSymbol *pSymbol = NULL;
    
    nEvents = SDL_PeepEvents(eventList, KEYBOARD_MAX_PEEP, SDL_GETEVENT, SDL_KEYDOWN,SDL_TEXTINPUT);
	if (nEvents == -1)
	{
		gEnv->pLog->LogError("SDL_GETEVENT error: %s", SDL_GetError());
		return;
	}
	for (int i = 0; i < nEvents; ++i)
	{
		type = eventList[i].type;
		if (type == SDL_KEYDOWN || type == SDL_KEYUP)
		{
			SDL_KeyboardEvent *const keyEvent = &eventList[i].key;
			m_lastKeySym = keyEvent->keysym.sym;
			m_lastMod = ConvertModifiers(keyEvent->keysym.mod);
		}
        // ignore this event. We can't skip it since the events are sampeled
        // in intervals and the value of SDL_TEXTEDITING is lower than
        // SDL_TEXTINPUT and higher than SDL_KEYUP
        if (type == SDL_TEXTEDITING) continue;

        if (type == SDL_KEYDOWN)
		{
			SDL_KeyboardEvent *const keyEvent = &eventList[i].key;
            SDL_Scancode keySym = keyEvent->keysym.scancode;
#if !defined(_RELEASE)
            didPressTild = (keySym == SDL_SCANCODE_GRAVE);
#endif
			pSymbol = DevSpecIdToSymbol((uint32)keySym);
			if (pSymbol == NULL)
				continue;
			pSymbol->state = eIS_Pressed;
			pSymbol->value = 1.f;
            // Check for CRTL+ALT combintaions
            if ((keyEvent->keysym.mod & KMOD_ALT) && (keyEvent->keysym.mod & KMOD_CTRL))
			{
                // CRLT + ALT + SHIFT + g = ungrab
                if (keySym == SDL_SCANCODE_G && keyEvent->keysym.mod & KMOD_SHIFT)
                    GetLinuxInput().GrabInput(false);
                // CRLT + ALT + g  = grab
                else if (keySym == SDL_SCANCODE_G)
                    GetLinuxInput().GrabInput(true);
			}

			PostEvent(pSymbol, keyEvent->keysym.mod);
            
			// TODO: Make consistent with other keyboard devices and fire OnInputEventUI with unicode char
			/*
             wchar_t unicode = keyEvent->keysym.unicode
             if (unicode)
             {
             SInputEvent event;
             event.keyName = pSymbol->name;
             event.deviceId = eDI_Mouse;
             event.timestamp = GetTickCount();
             if (keyMod != ~0)
             event.modifiers = ConvertModifiers(keyMod);
             else
             event.modifiers = 0; // FIXMCSDLMouse* pMouseE add mouse modifier support
             
             event.state = eIS_UI;
             event.inputChar = (wchar_t)unicode;
             event.value = 1.0f;
             event.pSymbol = pSymbol;
             GetIInput().PostInputEvent(event);
             }
             */
		}
		else if (type == SDL_KEYUP)
		{
			SDL_KeyboardEvent *const keyEvent = &eventList[i].key;
			SDL_Scancode keySym = keyEvent->keysym.scancode;
			pSymbol = DevSpecIdToSymbol((uint32)keySym);
			if (pSymbol == NULL)
				continue;
			pSymbol->state = eIS_Released;
			pSymbol->value = 0.f;
			PostEvent(pSymbol, keyEvent->keysym.mod);
		}
        else if (type == SDL_TEXTINPUT)
        {
#if !defined(_RELEASE)
            if (!didPressTild)
            {
#endif
                SDL_TextInputEvent *const txtEvent = &eventList[i].text;
                // try to convert the utf8 string to a single wchar_t character

								wstring strWide;
								CryStringUtils::UTF8ToWStr(&txtEvent->text[0], strWide);
								for(size_t i = 0; i < strWide.length(); ++i)
								{
									SInputEvent event;
									event.deviceType = m_deviceType;
									event.state = eIS_UI;
									event.value = 1.0f;
									event.inputChar = strWide[i];
									event.keyName = txtEvent->text;
									GetLinuxInput().PostInputEvent(event);
								}
#if !defined(_RELEASE)
            }
#endif
        }
        else
		{
            // Unexpect0;//ed event type.
			abort();
		}
    }
}
Ejemplo n.º 8
0
void gkMouse::Update(bool bFocus)
{
	HRESULT hr;
	
	if (!GetDirectInputDevice()) 
		return;

	m_deltas.zero();
	m_mouseWheel = 0;

	SInputSymbol* pSymbol = 0;
	EInputState newState;

	if (g_pInputCVars->i_mouse_buffered)
	{
		//memcpy(m_oldEvents, m_Events, sizeof(m_Events));
		//memset(m_Events,0,sizeof(m_Events));

		DIDEVICEOBJECTDATA Events[200];
		// // Buffer mouse input.
		DWORD nElements = 200;
		while (nElements > 0)
		{
			hr = GetDirectInputDevice()->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), Events, &nElements, 0);

			if (FAILED(hr) && Acquire())
			{
				// try again
				hr = GetDirectInputDevice()->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), Events, &nElements, 0);
			}
			
			if (FAILED(hr))
				return;

			if (nElements > 0)
			{
				for (int i = 0; i < (int)nElements; i++)
				{
					pSymbol = DevSpecIdToSymbol(Events[i].dwOfs);
					if (pSymbol)
					{
						// marcok: should actually process axis events here as` well,
						// but I'm not sure if the game can handle multiple move events

						if (pSymbol->type == SInputSymbol::Button)
						{
							if (Events[i].dwData&0x80)
							{
								pSymbol->state = eIS_Pressed;
								pSymbol->value = 1.0;
							}
							else
							{
								pSymbol->state = eIS_Released;
								pSymbol->value = 0.0;
							}
							PostEvent(pSymbol);
						}
					}
					switch (Events[i].dwOfs) 
					{
					case DIMOFS_X: 
						m_deltas.x += float((int)Events[i].dwData);
						break;
					case DIMOFS_Y: 
						m_deltas.y += float((int)Events[i].dwData);
						break; 
					case DIMOFS_Z:
						m_mouseWheel += float((int)Events[i].dwData);
						break;
					}
				}
			}
		}
	}
 	else
 	{
 		// Not buffered.
 		DIMOUSESTATE2 dims;
 		memset (&dims, 0, sizeof(dims));
 
 		hr = GetDirectInputDevice()->GetDeviceState(sizeof(DIMOUSESTATE2), &dims);	
 
 		if (FAILED(hr) && Acquire())
 		{
 			// try again
 			hr = GetDirectInputDevice()->GetDeviceState(sizeof(DIMOUSESTATE2), &dims);
 		}
 
 		if (SUCCEEDED(hr))
 		{
 			m_deltas.set((float)dims.lX, (float)dims.lY);
 			m_mouseWheel = (float)dims.lZ;
 		
			// mouse1 - mouse8
 			for (int i=0; i<8; ++i)
 			{
 				newState = (dims.rgbButtons[i]&0x80) ? eIS_Pressed : eIS_Released;
 				PostOnlyIfChanged(Symbol[i], newState);
 			}
 		}		
 	}

	//marcok: here the raw input already gets cooked a bit ... should be moved
	float mouseaccel = g_pInputCVars->i_mouse_accel;

	if (mouseaccel>0.0f)
	{
		m_deltas.x = m_deltas.x * (float)fabs(m_deltas.x * mouseaccel);
		m_deltas.y = m_deltas.y * (float)fabs(m_deltas.y * mouseaccel);

		CapDeltas(g_pInputCVars->i_mouse_accel_max);
	}

	SmoothDeltas(g_pInputCVars->i_mouse_smooth);

	//mouse wheel
	newState = (m_mouseWheel > 0.0f) ? eIS_Pressed : eIS_Released;
	PostOnlyIfChanged(Symbol[eKI_MouseWheelUp-KI_MOUSE_BASE], newState);

	newState = (m_mouseWheel < 0.0f) ? eIS_Pressed : eIS_Released;
	PostOnlyIfChanged(Symbol[eKI_MouseWheelDown-KI_MOUSE_BASE], newState);

	// mouse movements
	if (m_deltas.GetLength2()>0.0f || m_mouseWheel)
	{
		POINT point;
		GetCursorPos( &point );
		ScreenToClient( gEnv->pRenderer->GetWindowHwnd(), &point );

		Vec2i offset = gEnv->pRenderer->GetWindowOffset();


		pSymbol = Symbol[eKI_MouseX-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_deltas.x;
		pSymbol->value2 = point.x - offset.x;
		PostEvent(pSymbol);

		pSymbol = Symbol[eKI_MouseY-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_deltas.y;
		pSymbol->value2 = point.y - offset.y;
		PostEvent(pSymbol);

		pSymbol = Symbol[eKI_MouseZ-KI_MOUSE_BASE];
		pSymbol->state = eIS_Changed;
		pSymbol->value = m_mouseWheel;
		PostEvent(pSymbol);
	}

	//////////////////////////////////////////////////////////////////////////
	float inertia = g_pInputCVars->i_mouse_inertia;

	// mouse inertia
	if (inertia>0) 
	{
		float dt = gEnv->pTimer->GetFrameTime();
		if (dt>0.1f) dt=0.1f;
		m_deltas = (m_deltasInertia += (m_deltas-m_deltasInertia)*inertia*dt);
	}
}