312 lines
7.0 KiB
C++
312 lines
7.0 KiB
C++
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: The main manager of the UI
|
||
|
//
|
||
|
// $Revision: $
|
||
|
// $NoKeywords: $
|
||
|
//===========================================================================//
|
||
|
|
||
|
#include "inputmanager.h"
|
||
|
#include "legion.h"
|
||
|
#include "uimanager.h"
|
||
|
#include "inputsystem/iinputsystem.h"
|
||
|
#include "tier2/tier2.h"
|
||
|
#include "tier1/convar.h"
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Singleton accessor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static CInputManager s_InputManager;
|
||
|
extern CInputManager *g_pInputManager = &s_InputManager;
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Initialization
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CInputManager::Init()
|
||
|
{
|
||
|
// FIXME: Read keybindings from a file
|
||
|
m_KeyBindings.SetBinding( "w", "+forward" );
|
||
|
m_KeyBindings.SetBinding( "s", "+back" );
|
||
|
m_KeyBindings.SetBinding( "`", "toggleconsole" );
|
||
|
m_ButtonUpToEngine.ClearAll();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Add a command into the command queue
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CInputManager::AddCommand( const char *pCommand )
|
||
|
{
|
||
|
m_CommandBuffer.AddText( pCommand );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// FIXME! This is necessary only because of an artifact of how ConCommands used to work
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static ConCommand *FindNamedCommand( char const *name )
|
||
|
{
|
||
|
// look through the command list for all matches
|
||
|
ConCommandBase const *cmd = (ConCommandBase const *)vgui::icvar()->GetCommands();
|
||
|
while (cmd)
|
||
|
{
|
||
|
if (!Q_strcmp( name, cmd->GetName() ) )
|
||
|
{
|
||
|
if ( cmd->IsCommand() )
|
||
|
{
|
||
|
return ( ConCommand * )cmd;
|
||
|
}
|
||
|
}
|
||
|
cmd = cmd->GetNext();
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CInputManager::PrintConCommandBaseDescription( const ConCommandBase *pVar )
|
||
|
{
|
||
|
bool bMin, bMax;
|
||
|
float fMin, fMax;
|
||
|
const char *pStr;
|
||
|
|
||
|
Assert( pVar );
|
||
|
|
||
|
Color clr;
|
||
|
clr.SetColor( 255, 100, 100, 255 );
|
||
|
|
||
|
if ( !pVar->IsCommand() )
|
||
|
{
|
||
|
ConVar *var = ( ConVar * )pVar;
|
||
|
|
||
|
bMin = var->GetMin( fMin );
|
||
|
bMax = var->GetMax( fMax );
|
||
|
|
||
|
char const *value = NULL;
|
||
|
char tempVal[ 32 ];
|
||
|
|
||
|
if ( var->IsBitSet( FCVAR_NEVER_AS_STRING ) )
|
||
|
{
|
||
|
value = tempVal;
|
||
|
|
||
|
if ( fabs( (float)var->GetInt() - var->GetFloat() ) < 0.000001 )
|
||
|
{
|
||
|
Q_snprintf( tempVal, sizeof( tempVal ), "%d", var->GetInt() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Q_snprintf( tempVal, sizeof( tempVal ), "%f", var->GetFloat() );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
value = var->GetString();
|
||
|
}
|
||
|
|
||
|
if ( value )
|
||
|
{
|
||
|
Msg( "\"%s\" = \"%s\"", var->GetName(), value );
|
||
|
|
||
|
if ( Q_stricmp( value, var->GetDefault() ) )
|
||
|
{
|
||
|
Msg( " ( def. \"%s\" )", var->GetDefault() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( bMin )
|
||
|
{
|
||
|
Msg( " min. %f", fMin );
|
||
|
}
|
||
|
if ( bMax )
|
||
|
{
|
||
|
Msg( " max. %f", fMax );
|
||
|
}
|
||
|
|
||
|
Msg( "\n" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ConCommand *var = ( ConCommand * )pVar;
|
||
|
|
||
|
Msg( "\"%s\"\n", var->GetName() );
|
||
|
}
|
||
|
|
||
|
// PrintConCommandBaseFlags( pVar );
|
||
|
|
||
|
pStr = pVar->GetHelpText();
|
||
|
if ( pStr && pStr[0] )
|
||
|
{
|
||
|
Msg( " - %s\n", pStr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Per-frame update
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CInputManager::ProcessCommands( )
|
||
|
{
|
||
|
m_CommandBuffer.BeginProcessingCommands( 1 );
|
||
|
while ( m_CommandBuffer.DequeueNextCommand() )
|
||
|
{
|
||
|
const CCommand& args = m_CommandBuffer.GetCommand();
|
||
|
const ConCommandBase *pCommand = FindNamedCommand( args[ 0 ] );
|
||
|
if ( pCommand && pCommand->IsCommand() )
|
||
|
{
|
||
|
// FIXME: Um... yuck!?!
|
||
|
ConCommand *pConCommand = const_cast<ConCommand*>( static_cast<const ConCommand*>( pCommand ) );
|
||
|
pConCommand->Dispatch( args );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ConVar *pConVar = g_pCVar->FindVar( args[0] );
|
||
|
if ( !pConVar )
|
||
|
continue;
|
||
|
|
||
|
// perform a variable print or set
|
||
|
if ( args.ArgC() == 1 )
|
||
|
{
|
||
|
PrintConCommandBaseDescription( pConVar );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Note that we don't want the tokenized list, send down the entire string
|
||
|
// except for surrounding quotes
|
||
|
char remaining[1024];
|
||
|
const char *pArgS = args.ArgS();
|
||
|
int nLen = Q_strlen( pArgS );
|
||
|
bool bIsQuoted = pArgS[0] == '\"';
|
||
|
if ( !bIsQuoted )
|
||
|
{
|
||
|
Q_strncpy( remaining, args.ArgS(), sizeof(remaining) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
--nLen;
|
||
|
Q_strncpy( remaining, &pArgS[1], sizeof(remaining) );
|
||
|
}
|
||
|
|
||
|
// Now strip off any trailing spaces
|
||
|
char *p = remaining + nLen - 1;
|
||
|
while ( p >= remaining )
|
||
|
{
|
||
|
if ( *p > ' ' )
|
||
|
break;
|
||
|
|
||
|
*p-- = 0;
|
||
|
}
|
||
|
|
||
|
// Strip off ending quote
|
||
|
if ( bIsQuoted && p >= remaining )
|
||
|
{
|
||
|
if ( *p == '\"' )
|
||
|
{
|
||
|
*p = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pConVar->IsBitSet( FCVAR_NEVER_AS_STRING ) )
|
||
|
{
|
||
|
pConVar->SetValue( (float)atof( remaining ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pConVar->SetValue( remaining );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
m_CommandBuffer.EndProcessingCommands();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Per-frame update
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CInputManager::Update( )
|
||
|
{
|
||
|
char cmd[1024];
|
||
|
|
||
|
g_pInputSystem->PollInputState();
|
||
|
int nEventCount = g_pInputSystem->GetEventCount();
|
||
|
const InputEvent_t* pEvents = g_pInputSystem->GetEventData( );
|
||
|
for ( int i = 0; i < nEventCount; ++i )
|
||
|
{
|
||
|
if ( pEvents[i].m_nType == IE_Quit )
|
||
|
{
|
||
|
IGameManager::Stop();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
bool bBypassVGui = false;
|
||
|
switch( pEvents[i].m_nType )
|
||
|
{
|
||
|
case IE_AppActivated:
|
||
|
if ( pEvents[i].m_nData == 0 )
|
||
|
{
|
||
|
m_ButtonUpToEngine.ClearAll();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IE_ButtonReleased:
|
||
|
{
|
||
|
// This logic is necessary to deal with switching back + forth
|
||
|
// between vgui + the engine. If we downclick in the engine,
|
||
|
// the engine must get the upclick.
|
||
|
ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
|
||
|
if ( m_ButtonUpToEngine[ code ] )
|
||
|
{
|
||
|
m_ButtonUpToEngine.Clear( code );
|
||
|
bBypassVGui = true;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( !bBypassVGui )
|
||
|
{
|
||
|
if ( g_pUIManager->ProcessInputEvent( pEvents[i] ) )
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// FIXME: Add game keybinding system here
|
||
|
bool bButtonDown = ( pEvents[i].m_nType == IE_ButtonPressed );
|
||
|
bool bButtonUp = ( pEvents[i].m_nType == IE_ButtonReleased );
|
||
|
if ( bButtonDown || bButtonUp )
|
||
|
{
|
||
|
ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
|
||
|
if ( bButtonDown )
|
||
|
{
|
||
|
m_ButtonUpToEngine.Set( code );
|
||
|
}
|
||
|
const char *pBinding = m_KeyBindings.GetBindingForButton( code );
|
||
|
if ( !pBinding )
|
||
|
continue;
|
||
|
|
||
|
if ( pBinding[0] != '+' )
|
||
|
{
|
||
|
if ( bButtonDown )
|
||
|
{
|
||
|
m_CommandBuffer.AddText( pBinding );
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
Q_snprintf( cmd, sizeof(cmd), "%c%s %i\n", bButtonUp ? '-' : '+', &pBinding[1], code );
|
||
|
m_CommandBuffer.AddText( cmd );
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ProcessCommands();
|
||
|
}
|
||
|
|