//----------------------------------------------------------------------------- // Purpose: Deal with input //----------------------------------------------------------------------------- void C_VGuiScreen::ClientThink( void ) { BaseClass::ClientThink(); // FIXME: We should really be taking bob, shake, and roll into account // but if we did, then all the inputs would be generated multiple times // if the world was rendered multiple times (for things like water, etc.) vgui::Panel *pPanel = m_PanelWrapper.GetPanel(); if (!pPanel) return; C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if (!pLocalPlayer) return; // Generate a ray along the view direction Vector vecEyePosition = pLocalPlayer->EyePosition(); QAngle viewAngles = pLocalPlayer->EyeAngles( ); Vector viewDir, endPos; AngleVectors( viewAngles, &viewDir ); VectorMA( vecEyePosition, 1000.0f, viewDir, endPos ); // Compute cursor position... Ray_t lookDir; lookDir.Init( vecEyePosition, endPos ); float u, v; if (!IntersectWithRay( lookDir, &u, &v, NULL )) return; if ( ((u < 0) || (v < 0) || (u > 1) || (v > 1)) && !m_bLooseThinkNextFrame) return; // This will cause our panel to grab all input! g_pClientMode->ActivateInGameVGuiContext( pPanel ); // Convert (u,v) into (px,py) int px = (int)(u * m_nPixelWidth + 0.5f); int py = (int)(v * m_nPixelHeight + 0.5f); // Generate mouse input commands if ((px != m_nOldPx) || (py != m_nOldPy)) { g_InputInternal->InternalCursorMoved( px, py ); m_nOldPx = px; m_nOldPy = py; } if (m_nButtonPressed & IN_ATTACK) { g_InputInternal->InternalMousePressed(vgui::MOUSE_LEFT); } if (m_nButtonPressed & IN_ATTACK2) { g_InputInternal->InternalMousePressed(vgui::MOUSE_RIGHT); } if ( (m_nButtonReleased & IN_ATTACK) || m_bLooseThinkNextFrame) // for a button release on loosing focus { g_InputInternal->InternalMouseReleased(vgui::MOUSE_LEFT); } if (m_nButtonReleased & IN_ATTACK2) { g_InputInternal->InternalMouseReleased(vgui::MOUSE_RIGHT); } if ( m_bLooseThinkNextFrame == true ) { m_bLooseThinkNextFrame = false; SetNextClientThink( CLIENT_THINK_NEVER ); } g_pClientMode->DeactivateInGameVGuiContext( ); }
//----------------------------------------------------------------------------- // Purpose: Deal with input //----------------------------------------------------------------------------- void C_VGuiScreen::ClientThink( void ) { int nButtonsChanged = m_nOldButtonState ^ m_nButtonState; m_nOldButtonState = m_nButtonState; // Debounced button codes for pressed/released // UNDONE: Do we need auto-repeat? m_nButtonPressed = nButtonsChanged & m_nButtonState; // The changed ones still down are "pressed" m_nButtonReleased = nButtonsChanged & (~m_nButtonState); // The ones not down are "released" BaseClass::ClientThink(); // FIXME: We should really be taking bob, shake, and roll into account // but if we did, then all the inputs would be generated multiple times // if the world was rendered multiple times (for things like water, etc.) vgui::Panel *pPanel = m_PanelWrapper.GetPanel(); if (!pPanel) return; C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); if (!pLocalPlayer) return; // Generate a ray along the view direction Vector vecEyePosition = pLocalPlayer->EyePosition(); QAngle viewAngles = pLocalPlayer->EyeAngles( ); // Compute cursor position... Ray_t lookDir; Vector endPos; float u, v; // Viewmodel attached screens that take input need to have a moving cursor // Do a pick under the cursor as our selection Vector viewDir; AngleVectors( viewAngles, &viewDir ); VectorMA( vecEyePosition, 1000.0f, viewDir, endPos ); lookDir.Init( vecEyePosition, endPos ); if (!IntersectWithRay( lookDir, &u, &v, NULL )) return; if ( ((u < 0) || (v < 0) || (u > 1) || (v > 1)) && !m_bLoseThinkNextFrame) return; // This will cause our panel to grab all input! g_pClientMode->ActivateInGameVGuiContext( pPanel ); // Convert (u,v) into (px,py) int px = (int)(u * m_nPixelWidth + 0.5f); int py = (int)(v * m_nPixelHeight + 0.5f); // Generate mouse input commands if ((px != m_nOldPx) || (py != m_nOldPy)) { g_InputInternal->InternalCursorMoved( px, py ); m_nOldPx = px; m_nOldPy = py; } if (m_nButtonPressed & IN_ATTACK) { g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_PRESSED ); g_InputInternal->InternalMousePressed(MOUSE_LEFT); } if (m_nButtonPressed & IN_ATTACK2) { g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_PRESSED ); g_InputInternal->InternalMousePressed( MOUSE_RIGHT ); } if ( (m_nButtonReleased & IN_ATTACK) || m_bLoseThinkNextFrame) // for a button release on loosing focus { g_InputInternal->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_RELEASED ); g_InputInternal->InternalMouseReleased( MOUSE_LEFT ); } if (m_nButtonReleased & IN_ATTACK2) { g_InputInternal->SetMouseCodeState( MOUSE_RIGHT, vgui::BUTTON_RELEASED ); g_InputInternal->InternalMouseReleased( MOUSE_RIGHT ); } if ( m_bLoseThinkNextFrame == true ) { m_bLoseThinkNextFrame = false; SetNextClientThink( CLIENT_THINK_NEVER ); } g_pClientMode->DeactivateInGameVGuiContext( ); }