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); } }
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); } }