* (bug 2741) Adds support in the SDL client for many keys that were not

recognized.  For example, F13, F14, F15, WINDOWS, SCROLLLOCK, CAPSLOCK,
  WORLD_0 - WORLD_95, etc. (Christophe Cavalaria)

* (bug 2741) Adds the hard-coded toggleConsole bind Shift-Escape

* (bug 2741) Adds detailed explaination of SDL keyboard handling differences
  in the README file.
This commit is contained in:
Tony J. White = 2007-02-14 23:29:19 +00:00
parent da75e9fda8
commit d580c54e2d
5 changed files with 276 additions and 8 deletions

22
README
View file

@ -288,6 +288,28 @@ Multiuser Support on Windows systems
ioquake3.exe +set fs_homepath "c:\ioquake3" ioquake3.exe +set fs_homepath "c:\ioquake3"
Note that this cvar MUST be set as a command line parameter. Note that this cvar MUST be set as a command line parameter.
SDL Keyboard Differences
ioquake3 clients built againt SDL (e.g. Linux and Mac OS X) have different
keyboard behaviour than the original Quake3 clients.
* "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.
* SDL > 1.2.9 does not support disabling "Dead Key" recognition.
In order to send "Dead Key" characters (e.g. ~, ', `, and ^), you
must key a Space (or sometimes the same character again) after the
character to send it on many international keyboard layouts.
* The SDL client supports many more keys than the original Quake3 client.
For example the keys: "Windows", "SysReq", "ScrollLock", and "Break".
For non-US keyboards, all of the so called "World" keys are now
supported as well as F13, F14, F15, and the country-specific
mode/meta keys.
SDL's "Dead Key" behaviour makes the hard-coded toggleConsole binds ~ and `
annoying to use on many non-US keyboards. In response, an additional
toggleConsole bind has been added on the key combination Shift-Esc.
------------------------------------------------------------- Contributing ----- ------------------------------------------------------------- Contributing -----
Please send all patches to bugzilla (https://bugzilla.icculus.org), or join the Please send all patches to bugzilla (https://bugzilla.icculus.org), or join the

View file

@ -86,6 +86,9 @@ keyname_t keynames[] =
{"F10", K_F10}, {"F10", K_F10},
{"F11", K_F11}, {"F11", K_F11},
{"F12", K_F12}, {"F12", K_F12},
{"F13", K_F13},
{"F14", K_F14},
{"F15", K_F15},
{"INS", K_INS}, {"INS", K_INS},
{"DEL", K_DEL}, {"DEL", K_DEL},
@ -176,6 +179,116 @@ keyname_t keynames[] =
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands {"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"WORLD_0", K_WORLD_0},
{"WORLD_1", K_WORLD_1},
{"WORLD_2", K_WORLD_2},
{"WORLD_3", K_WORLD_3},
{"WORLD_4", K_WORLD_4},
{"WORLD_5", K_WORLD_5},
{"WORLD_6", K_WORLD_6},
{"WORLD_7", K_WORLD_7},
{"WORLD_8", K_WORLD_8},
{"WORLD_9", K_WORLD_9},
{"WORLD_10", K_WORLD_10},
{"WORLD_11", K_WORLD_11},
{"WORLD_12", K_WORLD_12},
{"WORLD_13", K_WORLD_13},
{"WORLD_14", K_WORLD_14},
{"WORLD_15", K_WORLD_15},
{"WORLD_16", K_WORLD_16},
{"WORLD_17", K_WORLD_17},
{"WORLD_18", K_WORLD_18},
{"WORLD_19", K_WORLD_19},
{"WORLD_20", K_WORLD_20},
{"WORLD_21", K_WORLD_21},
{"WORLD_22", K_WORLD_22},
{"WORLD_23", K_WORLD_23},
{"WORLD_24", K_WORLD_24},
{"WORLD_25", K_WORLD_25},
{"WORLD_26", K_WORLD_26},
{"WORLD_27", K_WORLD_27},
{"WORLD_28", K_WORLD_28},
{"WORLD_29", K_WORLD_29},
{"WORLD_30", K_WORLD_30},
{"WORLD_31", K_WORLD_31},
{"WORLD_32", K_WORLD_32},
{"WORLD_33", K_WORLD_33},
{"WORLD_34", K_WORLD_34},
{"WORLD_35", K_WORLD_35},
{"WORLD_36", K_WORLD_36},
{"WORLD_37", K_WORLD_37},
{"WORLD_38", K_WORLD_38},
{"WORLD_39", K_WORLD_39},
{"WORLD_40", K_WORLD_40},
{"WORLD_41", K_WORLD_41},
{"WORLD_42", K_WORLD_42},
{"WORLD_43", K_WORLD_43},
{"WORLD_44", K_WORLD_44},
{"WORLD_45", K_WORLD_45},
{"WORLD_46", K_WORLD_46},
{"WORLD_47", K_WORLD_47},
{"WORLD_48", K_WORLD_48},
{"WORLD_49", K_WORLD_49},
{"WORLD_50", K_WORLD_50},
{"WORLD_51", K_WORLD_51},
{"WORLD_52", K_WORLD_52},
{"WORLD_53", K_WORLD_53},
{"WORLD_54", K_WORLD_54},
{"WORLD_55", K_WORLD_55},
{"WORLD_56", K_WORLD_56},
{"WORLD_57", K_WORLD_57},
{"WORLD_58", K_WORLD_58},
{"WORLD_59", K_WORLD_59},
{"WORLD_60", K_WORLD_60},
{"WORLD_61", K_WORLD_61},
{"WORLD_62", K_WORLD_62},
{"WORLD_63", K_WORLD_63},
{"WORLD_64", K_WORLD_64},
{"WORLD_65", K_WORLD_65},
{"WORLD_66", K_WORLD_66},
{"WORLD_67", K_WORLD_67},
{"WORLD_68", K_WORLD_68},
{"WORLD_69", K_WORLD_69},
{"WORLD_70", K_WORLD_70},
{"WORLD_71", K_WORLD_71},
{"WORLD_72", K_WORLD_72},
{"WORLD_73", K_WORLD_73},
{"WORLD_74", K_WORLD_74},
{"WORLD_75", K_WORLD_75},
{"WORLD_76", K_WORLD_76},
{"WORLD_77", K_WORLD_77},
{"WORLD_78", K_WORLD_78},
{"WORLD_79", K_WORLD_79},
{"WORLD_80", K_WORLD_80},
{"WORLD_81", K_WORLD_81},
{"WORLD_82", K_WORLD_82},
{"WORLD_83", K_WORLD_83},
{"WORLD_84", K_WORLD_84},
{"WORLD_85", K_WORLD_85},
{"WORLD_86", K_WORLD_86},
{"WORLD_87", K_WORLD_87},
{"WORLD_88", K_WORLD_88},
{"WORLD_89", K_WORLD_89},
{"WORLD_90", K_WORLD_90},
{"WORLD_91", K_WORLD_91},
{"WORLD_92", K_WORLD_92},
{"WORLD_93", K_WORLD_93},
{"WORLD_94", K_WORLD_94},
{"WORLD_95", K_WORLD_95},
{"WINDOWS", K_SUPER},
{"COMPOSE", K_COMPOSE},
{"MODE", K_MODE},
{"HELP", K_HELP},
{"PRINT", K_PRINT},
{"SYSREQ", K_SYSREQ},
{"SCROLLOCK", K_SCROLLOCK },
{"BREAK", K_BREAK},
{"MENU", K_MENU},
{"POWER", K_POWER},
{"EURO", K_EURO},
{"UNDO", K_UNDO},
{NULL,0} {NULL,0}
}; };
@ -751,7 +864,7 @@ char *Key_KeynumToString( int keynum ) {
return "<KEY NOT FOUND>"; return "<KEY NOT FOUND>";
} }
if ( keynum < 0 || keynum > 255 ) { if ( keynum < 0 || keynum >= MAX_KEYS ) {
return "<OUT OF RANGE>"; return "<OUT OF RANGE>";
} }
@ -936,7 +1049,7 @@ void Key_WriteBindings( fileHandle_t f ) {
FS_Printf (f, "unbindall\n" ); FS_Printf (f, "unbindall\n" );
for (i=0 ; i<256 ; i++) { for (i=0 ; i<MAX_KEYS ; i++) {
if (keys[i].binding && keys[i].binding[0] ) { if (keys[i].binding && keys[i].binding[0] ) {
FS_Printf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keys[i].binding); FS_Printf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keys[i].binding);
@ -955,7 +1068,7 @@ Key_Bindlist_f
void Key_Bindlist_f( void ) { void Key_Bindlist_f( void ) {
int i; int i;
for ( i = 0 ; i < 256 ; i++ ) { for ( i = 0 ; i < MAX_KEYS ; i++ ) {
if ( keys[i].binding && keys[i].binding[0] ) { if ( keys[i].binding && keys[i].binding[0] ) {
Com_Printf( "%s \"%s\"\n", Key_KeynumToString(i), keys[i].binding ); Com_Printf( "%s \"%s\"\n", Key_KeynumToString(i), keys[i].binding );
} }
@ -1066,7 +1179,8 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
#endif #endif
// 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 == '`' || key == '~' ||
( key == K_ESCAPE && keys[K_SHIFT].down ) ) {
if (!down) { if (!down) {
return; return;
} }

View file

@ -151,7 +151,116 @@ typedef enum {
K_AUX15, K_AUX15,
K_AUX16, K_AUX16,
K_LAST_KEY // this had better be <256! K_WORLD_0,
K_WORLD_1,
K_WORLD_2,
K_WORLD_3,
K_WORLD_4,
K_WORLD_5,
K_WORLD_6,
K_WORLD_7,
K_WORLD_8,
K_WORLD_9,
K_WORLD_10,
K_WORLD_11,
K_WORLD_12,
K_WORLD_13,
K_WORLD_14,
K_WORLD_15,
K_WORLD_16,
K_WORLD_17,
K_WORLD_18,
K_WORLD_19,
K_WORLD_20,
K_WORLD_21,
K_WORLD_22,
K_WORLD_23,
K_WORLD_24,
K_WORLD_25,
K_WORLD_26,
K_WORLD_27,
K_WORLD_28,
K_WORLD_29,
K_WORLD_30,
K_WORLD_31,
K_WORLD_32,
K_WORLD_33,
K_WORLD_34,
K_WORLD_35,
K_WORLD_36,
K_WORLD_37,
K_WORLD_38,
K_WORLD_39,
K_WORLD_40,
K_WORLD_41,
K_WORLD_42,
K_WORLD_43,
K_WORLD_44,
K_WORLD_45,
K_WORLD_46,
K_WORLD_47,
K_WORLD_48,
K_WORLD_49,
K_WORLD_50,
K_WORLD_51,
K_WORLD_52,
K_WORLD_53,
K_WORLD_54,
K_WORLD_55,
K_WORLD_56,
K_WORLD_57,
K_WORLD_58,
K_WORLD_59,
K_WORLD_60,
K_WORLD_61,
K_WORLD_62,
K_WORLD_63,
K_WORLD_64,
K_WORLD_65,
K_WORLD_66,
K_WORLD_67,
K_WORLD_68,
K_WORLD_69,
K_WORLD_70,
K_WORLD_71,
K_WORLD_72,
K_WORLD_73,
K_WORLD_74,
K_WORLD_75,
K_WORLD_76,
K_WORLD_77,
K_WORLD_78,
K_WORLD_79,
K_WORLD_80,
K_WORLD_81,
K_WORLD_82,
K_WORLD_83,
K_WORLD_84,
K_WORLD_85,
K_WORLD_86,
K_WORLD_87,
K_WORLD_88,
K_WORLD_89,
K_WORLD_90,
K_WORLD_91,
K_WORLD_92,
K_WORLD_93,
K_WORLD_94,
K_WORLD_95,
K_SUPER,
K_COMPOSE,
K_MODE,
K_HELP,
K_PRINT,
K_SYSREQ,
K_SCROLLOCK,
K_BREAK,
K_MENU,
K_EURO,
K_UNDO,
K_LAST_KEY // this had better be < MAX_KEYS!
} keyNum_t; } keyNum_t;

View file

@ -21,7 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "keycodes.h" #include "keycodes.h"
#define MAX_KEYS 256 #define MAX_KEYS 384
typedef struct { typedef struct {
qboolean down; qboolean down;

View file

@ -225,6 +225,9 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
case SDLK_F10: *key = K_F10; break; case SDLK_F10: *key = K_F10; break;
case SDLK_F11: *key = K_F11; break; case SDLK_F11: *key = K_F11; break;
case SDLK_F12: *key = K_F12; break; case SDLK_F12: *key = K_F12; break;
case SDLK_F13: *key = K_F13; break;
case SDLK_F14: *key = K_F14; break;
case SDLK_F15: *key = K_F15; break;
// bk001206 - from Ryan's Fakk2 // bk001206 - from Ryan's Fakk2
case SDLK_BACKSPACE: *key = K_BACKSPACE; break; // ctrl-h case SDLK_BACKSPACE: *key = K_BACKSPACE; break; // ctrl-h
@ -243,15 +246,35 @@ static const char *XLateKey(SDL_keysym *keysym, int *key)
case SDLK_RALT: case SDLK_RALT:
case SDLK_LALT: *key = K_ALT; break; case SDLK_LALT: *key = K_ALT; break;
case SDLK_LSUPER:
case SDLK_RSUPER: *key = K_SUPER; break;
case SDLK_KP5: *key = K_KP_5; break; case SDLK_KP5: *key = K_KP_5; break;
case SDLK_INSERT: *key = K_INS; break; case SDLK_INSERT: *key = K_INS; break;
case SDLK_KP0: *key = K_KP_INS; break; case SDLK_KP0: *key = K_KP_INS; break;
case SDLK_KP_MULTIPLY: *key = '*'; break; case SDLK_KP_MULTIPLY: *key = K_KP_STAR; break;
case SDLK_KP_PLUS: *key = K_KP_PLUS; break; case SDLK_KP_PLUS: *key = K_KP_PLUS; break;
case SDLK_KP_MINUS: *key = K_KP_MINUS; break; case SDLK_KP_MINUS: *key = K_KP_MINUS; break;
case SDLK_KP_DIVIDE: *key = K_KP_SLASH; break; case SDLK_KP_DIVIDE: *key = K_KP_SLASH; break;
default: break; case SDLK_MODE: *key = K_MODE; break;
case SDLK_COMPOSE: *key = K_COMPOSE; break;
case SDLK_HELP: *key = K_HELP; break;
case SDLK_PRINT: *key = K_PRINT; break;
case SDLK_SYSREQ: *key = K_SYSREQ; break;
case SDLK_BREAK: *key = K_BREAK; break;
case SDLK_MENU: *key = K_MENU; break;
case SDLK_POWER: *key = K_POWER; break;
case SDLK_EURO: *key = K_EURO; break;
case SDLK_UNDO: * key = K_UNDO; break;
case SDLK_SCROLLOCK: *key = K_SCROLLOCK; break;
case SDLK_NUMLOCK: *key = K_KP_NUMLOCK; break;
case SDLK_CAPSLOCK: *key = K_CAPSLOCK; break;
default:
if (keysym->sym >= SDLK_WORLD_0 && keysym->sym <= SDLK_WORLD_95)
*key = (keysym->sym - SDLK_WORLD_0) + K_WORLD_0;
break;
} }
if( keysym->unicode <= 127 ) // maps to ASCII? if( keysym->unicode <= 127 ) // maps to ASCII?