* Add Com_HexStrToInt

* Fixed some whacky indentation in q_shared.c
* Allow single character keys e.g. 'c' to be used in cl_consoleKeys in addition
  to ASCII characters
* Experimental code to ignore dead keys
This commit is contained in:
Tim Angus 2008-09-05 23:38:35 +00:00
parent b6b19caadd
commit b2d87c4b2a
6 changed files with 137 additions and 156 deletions

13
README
View file

@ -399,15 +399,14 @@ SDL Keyboard Differences
If you use such a keyboard layout, you can set the cvar cl_consoleKeys. This
is a space delimited list of key names that will toggle the console. The key
names are the usual Q3 names e.g. "BACKSPACE", "PAUSE", "WINDOWS" etc. It's
also possible to use ASCII characters, either by hexadecimal number e.g.
"0x7e" (equivalent to ~) or directly by character. Some example values for
cl_consoleKeys:
names are the usual Q3 names e.g. "~", "`", "c", "BACKSPACE", "PAUSE",
"WINDOWS" etc. It's also possible to use ASCII characters, by hexadecimal
number. Some example values for cl_consoleKeys:
"0x7e 0x60" Toggle on ~ or ` (the default)
"~ ` 0x7e 0x60" Toggle on ~ or ` (the default)
"WINDOWS" Toggle on the Windows key
"c" Toggle on the c character
"C" Toggle on the C character (Shift-c)
"c" Toggle on the c key
"0x43" Toggle on the C character (Shift-c)
"PAUSE F1 PGUP" Toggle on the Pause, F1 or Page Up keys
Note that when you elect a set of console keys or characters, they cannot

View file

@ -776,7 +776,6 @@ qboolean Key_IsDown( int keynum ) {
return keys[keynum].down;
}
/*
===================
Key_StringToKeynum
@ -801,28 +800,12 @@ int Key_StringToKeynum( char *str ) {
}
// check for hex code
if ( str[0] == '0' && str[1] == 'x' && strlen( str ) == 4) {
int n1, n2;
if ( strlen( str ) == 4 ) {
int n = Com_HexStrToInt( str );
n1 = str[2];
if ( n1 >= '0' && n1 <= '9' ) {
n1 -= '0';
} else if ( n1 >= 'a' && n1 <= 'f' ) {
n1 = n1 - 'a' + 10;
} else {
n1 = 0;
if ( n >= 0 ) {
return n;
}
n2 = str[3];
if ( n2 >= '0' && n2 <= '9' ) {
n2 -= '0';
} else if ( n2 >= 'a' && n2 <= 'f' ) {
n2 = n2 - 'a' + 10;
} else {
n2 = 0;
}
return n1 * 16 + n2;
}
// scan for a text match

View file

@ -3079,8 +3079,8 @@ void CL_Init( void ) {
cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE);
// 0x7e = ~ and 0x60 = `
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "0x7e 0x60", CVAR_ARCHIVE);
// ~ and `, as keys and characters
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE);
// userinfo
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );

View file

@ -361,48 +361,48 @@ int COM_Compress( char *data_p ) {
in++;
if ( *in )
in += 2;
// record when we hit a newline
} else if ( c == '\n' || c == '\r' ) {
newline = qtrue;
in++;
// record when we hit whitespace
} else if ( c == ' ' || c == '\t') {
whitespace = qtrue;
in++;
// an actual token
// record when we hit a newline
} else if ( c == '\n' || c == '\r' ) {
newline = qtrue;
in++;
// record when we hit whitespace
} else if ( c == ' ' || c == '\t') {
whitespace = qtrue;
in++;
// an actual token
} else {
// if we have a pending newline, emit it (and it counts as whitespace)
if (newline) {
*out++ = '\n';
newline = qfalse;
whitespace = qfalse;
} if (whitespace) {
*out++ = ' ';
whitespace = qfalse;
}
// if we have a pending newline, emit it (and it counts as whitespace)
if (newline) {
*out++ = '\n';
newline = qfalse;
whitespace = qfalse;
} if (whitespace) {
*out++ = ' ';
whitespace = qfalse;
}
// copy quoted strings unmolested
if (c == '"') {
*out++ = c;
in++;
while (1) {
c = *in;
if (c && c != '"') {
*out++ = c;
in++;
} else {
break;
}
}
if (c == '"') {
*out++ = c;
in++;
}
} else {
*out = c;
out++;
in++;
}
// copy quoted strings unmolested
if (c == '"') {
*out++ = c;
in++;
while (1) {
c = *in;
if (c && c != '"') {
*out++ = c;
in++;
} else {
break;
}
}
if (c == '"') {
*out++ = c;
in++;
}
} else {
*out = c;
out++;
in++;
}
}
}
}
@ -512,62 +512,6 @@ char *COM_ParseExt( char **data_p, qboolean allowLineBreaks )
return com_token;
}
#if 0
// no longer used
/*
===============
COM_ParseInfos
===============
*/
int COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] ) {
char *token;
int count;
char key[MAX_TOKEN_CHARS];
count = 0;
while ( 1 ) {
token = COM_Parse( &buf );
if ( !token[0] ) {
break;
}
if ( strcmp( token, "{" ) ) {
Com_Printf( "Missing { in info file\n" );
break;
}
if ( count == max ) {
Com_Printf( "Max infos exceeded\n" );
break;
}
infos[count][0] = 0;
while ( 1 ) {
token = COM_ParseExt( &buf, qtrue );
if ( !token[0] ) {
Com_Printf( "Unexpected end of info file\n" );
break;
}
if ( !strcmp( token, "}" ) ) {
break;
}
Q_strncpyz( key, token, sizeof( key ) );
token = COM_ParseExt( &buf, qfalse );
if ( !token[0] ) {
strcpy( token, "<NULL>" );
}
Info_SetValueForKey( infos[count], key, token );
}
count++;
}
return count;
}
#endif
/*
==================
COM_MatchToken
@ -669,6 +613,44 @@ void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m) {
COM_MatchToken( buf_p, ")" );
}
/*
===================
Com_HexStrToInt
===================
*/
int Com_HexStrToInt( const char *str )
{
if ( !str || !str[ 0 ] )
return -1;
// check for hex code
if( str[ 0 ] == '0' && str[ 1 ] == 'x' )
{
int i, n = 0;
for( i = 2; i < strlen( str ); i++ )
{
char digit;
n *= 16;
digit = tolower( str[ i ] );
if( digit >= '0' && digit <= '9' )
digit -= '0';
else if( digit >= 'a' && digit <= 'f' )
digit = digit - 'a' + 10;
else
return -1;
n += digit;
}
return n;
}
return -1;
}
/*
============================================================================

View file

@ -652,6 +652,7 @@ void SkipRestOfLine ( char **data );
void Parse1DMatrix (char **buf_p, int x, float *m);
void Parse2DMatrix (char **buf_p, int y, int x, float *m);
void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
int Com_HexStrToInt( const char *str );
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));

View file

@ -84,7 +84,7 @@ static void IN_PrintKey( const SDL_keysym *keysym, keyNum_t key, qboolean down )
else
Com_Printf( " " );
Com_Printf( "0x%hx \"%s\"", keysym->scancode,
Com_Printf( "0x%02x \"%s\"", keysym->scancode,
SDL_GetKeyName( keysym->sym ) );
if( keysym->mod & KMOD_LSHIFT ) Com_Printf( " KMOD_LSHIFT" );
@ -100,11 +100,11 @@ static void IN_PrintKey( const SDL_keysym *keysym, keyNum_t key, qboolean down )
if( keysym->mod & KMOD_MODE ) Com_Printf( " KMOD_MODE" );
if( keysym->mod & KMOD_RESERVED ) Com_Printf( " KMOD_RESERVED" );
Com_Printf( " Q:%d(%s)", key, Key_KeynumToString( key ) );
Com_Printf( " Q:0x%02x(%s)", key, Key_KeynumToString( key ) );
if( keysym->unicode )
{
Com_Printf( " U:%d", keysym->unicode );
Com_Printf( " U:0x%02x", keysym->unicode );
if( keysym->unicode > ' ' && keysym->unicode < '~' )
Com_Printf( "(%c)", (char)keysym->unicode );
@ -120,7 +120,7 @@ static void IN_PrintKey( const SDL_keysym *keysym, keyNum_t key, qboolean down )
IN_IsConsoleKey
===============
*/
static qboolean IN_IsConsoleKey( keyNum_t key, const char character )
static qboolean IN_IsConsoleKey( keyNum_t key, const unsigned char character )
{
typedef struct consoleKey_s
{
@ -133,7 +133,7 @@ static qboolean IN_IsConsoleKey( keyNum_t key, const char character )
union
{
keyNum_t key;
char character;
unsigned char character;
} u;
} consoleKey_t;
@ -153,34 +153,36 @@ static qboolean IN_IsConsoleKey( keyNum_t key, const char character )
while( numConsoleKeys < MAX_CONSOLE_KEYS )
{
consoleKey_t *c = &consoleKeys[ numConsoleKeys ];
char *keyName;
int charCode = 0;
token = COM_Parse( &text_p );
if( !token[ 0 ] )
break;
c->u.key = Key_StringToKeynum( token );
if( strlen( token ) == 4 )
charCode = Com_HexStrToInt( token );
// 0 isn't a key
if( c->u.key == 0 )
continue;
keyName = Key_KeynumToString( c->u.key );
if( strlen( keyName ) == 1 )
if( charCode > 0 )
{
c->type = CHARACTER;
c->u.character = *keyName;
c->u.character = (unsigned char)charCode;
}
else
{
c->type = KEY;
c->u.key = Key_StringToKeynum( token );
// 0 isn't a key
if( c->u.key <= 0 )
continue;
}
numConsoleKeys++;
}
}
// Use the character in preference to the key name
if( character != '\0' )
// If the character is the same as the key, prefer the character
if( key == character )
key = 0;
for( i = 0; i < numConsoleKeys; i++ )
@ -212,7 +214,7 @@ IN_TranslateSDLToQ3Key
static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
keyNum_t *key, qboolean down )
{
static char buf[ 2 ] = { '\0', '\0' };
static unsigned char buf[ 2 ] = { '\0', '\0' };
*buf = '\0';
*key = 0;
@ -311,9 +313,9 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
}
}
if( down && keysym->unicode && !( keysym->unicode & 0xFF80 ) )
if( down && keysym->unicode && !( keysym->unicode & 0xFF00 ) )
{
char ch = (char)keysym->unicode & 0x7F;
unsigned char ch = (unsigned char)keysym->unicode & 0xFF;
switch( ch )
{
@ -333,6 +335,17 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
if( in_keyboardDebug->integer )
IN_PrintKey( keysym, *key, down );
// Keys that have ASCII names but produce no character are probably
// dead keys -- ignore them
if( down && strlen( Key_KeynumToString( *key ) ) == 1 &&
keysym->unicode == 0 )
{
if( in_keyboardDebug->integer )
Com_Printf( " Ignored dead key '%c'\n", *key );
*key = 0;
}
if( IN_IsConsoleKey( *key, *buf ) )
{
// Console keys can't be bound or generate characters
@ -340,7 +353,11 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
*buf = '\0';
}
return buf;
// Don't allow extended ASCII to generate characters
if( *buf & 0x80 )
*buf = '\0';
return (char *)buf;
}
#ifdef MACOS_X_ACCELERATION_HACK
@ -817,7 +834,7 @@ IN_ProcessEvents
static void IN_ProcessEvents( void )
{
SDL_Event e;
const char *p = NULL;
const char *character = NULL;
keyNum_t key = 0;
if( !SDL_WasInit( SDL_INIT_VIDEO ) )
@ -840,20 +857,19 @@ static void IN_ProcessEvents( void )
switch( e.type )
{
case SDL_KEYDOWN:
p = IN_TranslateSDLToQ3Key( &e.key.keysym, &key, qtrue );
character = IN_TranslateSDLToQ3Key( &e.key.keysym, &key, qtrue );
if( key )
Com_QueueEvent( 0, SE_KEY, key, qtrue, 0, NULL );
if( p )
{
while( *p )
Com_QueueEvent( 0, SE_CHAR, *p++, 0, 0, NULL );
}
if( character )
Com_QueueEvent( 0, SE_CHAR, *character, 0, 0, NULL );
break;
case SDL_KEYUP:
IN_TranslateSDLToQ3Key( &e.key.keysym, &key, qfalse );
Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL );
if( key )
Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL );
break;
case SDL_MOUSEMOTION: