Ejemplo n.º 1
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.º 2
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);
	}
}