* Revert 'Handle dead keys more gracefully by taking a "best guess" rather than

ignoring completely' from r1459; it can't ever work acceptably, especially on
  azerty/qwertz layouts
* Make the ordering of the output from in_keyboardDebug more sensible
* Add cl_consoleKeys cvar, a space delimited list of key names or characters
  that toggle the console
This commit is contained in:
Tim Angus 2008-08-28 22:05:34 +00:00
parent f1faa1d12a
commit c0328ab4f6
6 changed files with 122 additions and 56 deletions

45
README
View File

@ -101,6 +101,10 @@ New cvars
cl_autoRecordDemo - record a new demo on each map change cl_autoRecordDemo - record a new demo on each map change
cl_aviFrameRate - the framerate to use when capturing video cl_aviFrameRate - the framerate to use when capturing video
cl_aviMotionJpeg - use the mjpeg codec when capturing video cl_aviMotionJpeg - use the mjpeg codec when capturing video
cl_guidServerUniq - makes cl_guid unique for each server
cl_cURLLib - filename of cURL library to load
cl_consoleKeys - space delimited list of key names or
characters that toggle the console
s_useOpenAL - use the OpenAL sound backend if available s_useOpenAL - use the OpenAL sound backend if available
s_alPrecache - cache OpenAL sounds before use s_alPrecache - cache OpenAL sounds before use
@ -138,8 +142,6 @@ New cvars
in_joystickNo - select which joystick to use in_joystickNo - select which joystick to use
in_keyboardDebug - print keyboard debug info in_keyboardDebug - print keyboard debug info
r_ext_texture_filter_anisotropic - anisotropic texture filtering r_ext_texture_filter_anisotropic - anisotropic texture filtering
cl_guidServerUniq - makes cl_guid unique for each server
cl_cURLLib - filename of cURL library to load
sv_dlURL - the base of the HTTP or FTP site that sv_dlURL - the base of the HTTP or FTP site that
holds custom pk3 files for your server holds custom pk3 files for your server
@ -379,20 +381,39 @@ SDL Keyboard Differences
* "Caps Lock" and "Num Lock" can not be used as normal binds since they * "Caps Lock" and "Num Lock" can not be used as normal binds since they
do not send a KEYUP event until the key is pressed again. do not send a KEYUP event until the key is pressed again.
* SDL > 1.2.9 does not support disabling "Dead Key" recognition. * SDL > 1.2.9 does not support disabling dead key recognition. In order to
In order to send "Dead Key" characters (e.g. ~, ', `, and ^), you send dead key characters (e.g. ~, ', `, and ^), you must key a Space (or
must key a Space (or sometimes the same character again) after the sometimes the same character again) after the character to send it on
character to send it on many international keyboard layouts. many international keyboard layouts.
* The SDL client supports many more keys than the original Quake3 client. * The SDL client supports many more keys than the original Quake3 client.
For example the keys: "Windows", "SysReq", "ScrollLock", and "Break". For example the keys: "Windows", "SysReq", "ScrollLock", and "Break".
For non-US keyboards, all of the so called "World" keys are now For non-US keyboards, all of the so called "World" keys are now supported
supported as well as F13, F14, F15, and the country-specific as well as F13, F14, F15, and the country-specific mode/meta keys.
mode/meta keys.
SDL's "Dead Key" behaviour makes the hard-coded toggleConsole binds ~ and ` On many international layouts the default console toggle keys are also dead
annoying to use on many non-US keyboards. In response, an additional keys, meaning that dropping the console potentially results in
toggleConsole bind has been added on the key combination Shift-Esc. unintentionally initiating the keying of a dead key. Futhermore SDL 1.2's
dead key support is broken by design and Q3 doesn't support non-ASCII text
entry, so the chances are you won't get the correct character anyway.
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:
"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)
"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
then be used for binding, nor will they generate characters when entering
text. Also, in addition to the nominated console keys, Shift-ESC is hard
coded to always toggle the console.
Mouse Input On Windows Mouse Input On Windows
ioq3 uses SDL to abstract away as much as possible from platform specific ioq3 uses SDL to abstract away as much as possible from platform specific

View File

@ -1172,7 +1172,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
} }
// console key is hardcoded, so the user can never unbind it // console key is hardcoded, so the user can never unbind it
if (key == '`' || key == '~' || if (key == K_CONSOLE ||
( key == K_ESCAPE && keys[K_SHIFT].down ) ) { ( key == K_ESCAPE && keys[K_SHIFT].down ) ) {
if (!down) { if (!down) {
return; return;
@ -1315,11 +1315,6 @@ Normal keyboard characters, already shifted / capslocked / etc
=================== ===================
*/ */
void CL_CharEvent( int key ) { void CL_CharEvent( int key ) {
// the console key should never be used as a char
if ( key == '`' || key == '~' ) {
return;
}
// delete is not a printable character and is // delete is not a printable character and is
// otherwise handled by Field_KeyDownEvent // otherwise handled by Field_KeyDownEvent
if ( key == 127 ) { if ( key == 127 ) {

View File

@ -96,6 +96,8 @@ cvar_t *cl_lanForcePackets;
cvar_t *cl_guidServerUniq; cvar_t *cl_guidServerUniq;
cvar_t *cl_consoleKeys;
clientActive_t cl; clientActive_t cl;
clientConnection_t clc; clientConnection_t clc;
clientStatic_t cls; clientStatic_t cls;
@ -3065,6 +3067,9 @@ void CL_Init( void ) {
cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE); cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE);
// 0x7e = ~ and 0x60 = `
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "0x7e 0x60", CVAR_ARCHIVE);
// userinfo // userinfo
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("rate", "3000", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("rate", "3000", CVAR_USERINFO | CVAR_ARCHIVE );

View File

@ -401,6 +401,8 @@ extern cvar_t *cl_inGameVideo;
extern cvar_t *cl_lanForcePackets; extern cvar_t *cl_lanForcePackets;
extern cvar_t *cl_autoRecordDemo; extern cvar_t *cl_autoRecordDemo;
extern cvar_t *cl_consoleKeys;
#ifdef USE_MUMBLE #ifdef USE_MUMBLE
extern cvar_t *cl_useMumble; extern cvar_t *cl_useMumble;
extern cvar_t *cl_mumbleScale; extern cvar_t *cl_mumbleScale;
@ -489,6 +491,7 @@ void IN_CenterView (void);
void CL_VerifyCode( void ); void CL_VerifyCode( void );
float CL_KeyState (kbutton_t *key); float CL_KeyState (kbutton_t *key);
int Key_StringToKeynum( char *str );
char *Key_KeynumToString (int keynum); char *Key_KeynumToString (int keynum);
// //

View File

@ -260,6 +260,9 @@ typedef enum {
K_EURO, K_EURO,
K_UNDO, K_UNDO,
// Pseudo-key that brings the console down
K_CONSOLE,
MAX_KEYS MAX_KEYS
} keyNum_t; } keyNum_t;

View File

@ -77,7 +77,7 @@ static cvar_t *in_joystickNo = NULL;
IN_PrintKey IN_PrintKey
=============== ===============
*/ */
static void IN_PrintKey( const SDL_keysym *keysym, int key, qboolean down ) static void IN_PrintKey( const SDL_keysym *keysym, keyNum_t key, qboolean down )
{ {
if( down ) if( down )
Com_Printf( "+ " ); Com_Printf( "+ " );
@ -100,15 +100,66 @@ static void IN_PrintKey( const SDL_keysym *keysym, int key, qboolean down )
if( keysym->mod & KMOD_MODE ) Com_Printf( " KMOD_MODE" ); if( keysym->mod & KMOD_MODE ) Com_Printf( " KMOD_MODE" );
if( keysym->mod & KMOD_RESERVED ) Com_Printf( " KMOD_RESERVED" ); if( keysym->mod & KMOD_RESERVED ) Com_Printf( " KMOD_RESERVED" );
Com_Printf( " Q:%d(%s)", key, Key_KeynumToString( key ) );
if( keysym->unicode ) if( keysym->unicode )
{ {
Com_Printf( " %d", keysym->unicode ); Com_Printf( " U:%d", keysym->unicode );
if( keysym->unicode > ' ' && keysym->unicode < '~' ) if( keysym->unicode > ' ' && keysym->unicode < '~' )
Com_Printf( "(%c)", (char)keysym->unicode ); Com_Printf( "(%c)", (char)keysym->unicode );
} }
Com_Printf( " %d(%s)\n", key, Key_KeynumToString( key ) ); Com_Printf( "\n" );
}
#define MAX_CONSOLE_KEYS 16
/*
===============
IN_IsConsoleKey
===============
*/
static qboolean IN_IsConsoleKey( keyNum_t key, const char *buf )
{
static int consoleKeys[ MAX_CONSOLE_KEYS ];
static int numConsoleKeys = 0;
int i;
// Only parse the variable when it changes
if( cl_consoleKeys->modified )
{
char *text_p, *token;
cl_consoleKeys->modified = qfalse;
text_p = cl_consoleKeys->string;
numConsoleKeys = 0;
while( numConsoleKeys < MAX_CONSOLE_KEYS )
{
token = COM_Parse( &text_p );
if( !token[ 0 ] )
break;
consoleKeys[ numConsoleKeys++ ] =
Key_StringToKeynum( token );
}
}
// If key is ASCII, use the character instead
if( key >= K_SPACE && key < K_BACKSPACE )
key = 0;
for( i = 0; i < numConsoleKeys; i++ )
{
if( !consoleKeys[ i ] )
continue;
if( consoleKeys[ i ] == key || consoleKeys[ i ] == *buf )
return qtrue;
}
return qfalse;
} }
/* /*
@ -117,7 +168,7 @@ IN_TranslateSDLToQ3Key
=============== ===============
*/ */
static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
int *key, qboolean down ) keyNum_t *key, qboolean down )
{ {
static char buf[ 2 ] = { '\0', '\0' }; static char buf[ 2 ] = { '\0', '\0' };
@ -131,7 +182,7 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
} }
else else
{ {
switch (keysym->sym) switch( keysym->sym )
{ {
case SDLK_PAGEUP: *key = K_PGUP; break; case SDLK_PAGEUP: *key = K_PGUP; break;
case SDLK_KP9: *key = K_KP_PGUP; break; case SDLK_KP9: *key = K_KP_PGUP; break;
@ -218,47 +269,35 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym,
} }
} }
if( down ) if( down && keysym->unicode && !( keysym->unicode & 0xFF80 ) )
{ {
if( keysym->unicode && !( keysym->unicode & 0xFF80 ) ) char ch = (char)keysym->unicode & 0x7F;
switch( ch )
{ {
char ch = (char)keysym->unicode & 0x7F; case 127: // ASCII delete
if( *key != K_DEL )
{
// ctrl-h
*buf = CTRL('h');
break;
}
// fallthrough
switch( ch ) default: *buf = ch; break;
{
// So the key marked ~ always drops the console
case '~': *key = '~'; break;
case 127: // ASCII delete
if( *key != K_DEL )
{
// ctrl-h
*buf = CTRL('h');
break;
}
// fallthrough
default: *buf = ch; break;
}
}
else
{
// Unicode character which isn't ASCII, possibly the character
// following a dead key. Fallback on what SDL calls the key
const char *keyString = SDL_GetKeyName( keysym->sym );
if( strlen( keyString ) == 1 )
*buf = *keyString;
} }
} }
// Never allow a '~' SE_CHAR event to be generated
if( *key == '~' )
*buf = '\0';
if( in_keyboardDebug->integer ) if( in_keyboardDebug->integer )
IN_PrintKey( keysym, *key, down ); IN_PrintKey( keysym, *key, down );
if( IN_IsConsoleKey( *key, buf ) )
{
// Console keys can't be bound or generate characters
*key = K_CONSOLE;
*buf = '\0';
}
return buf; return buf;
} }
@ -737,7 +776,7 @@ static void IN_ProcessEvents( void )
{ {
SDL_Event e; SDL_Event e;
const char *p = NULL; const char *p = NULL;
int key = 0; keyNum_t key = 0;
if( !SDL_WasInit( SDL_INIT_VIDEO ) ) if( !SDL_WasInit( SDL_INIT_VIDEO ) )
return; return;