aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea>2009-10-03 23:35:07 +0000
committerthilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea>2009-10-03 23:35:07 +0000
commit996d669605a9feb39754356ab0779847b46d10af (patch)
tree6ddba82155c4a00879c61ce79202bfd5666a5b9a
parentc7fa915d9d35b3b7f232470cef98d783cde923ac (diff)
downloadioquake3-aero-996d669605a9feb39754356ab0779847b46d10af.tar.gz
ioquake3-aero-996d669605a9feb39754356ab0779847b46d10af.zip
Rewrite of key event processing, thanks to /dev/humancontroller and Ben Millwood. https://bugzilla.icculus.org/show_bug.cgi?id=3374
git-svn-id: svn://svn.icculus.org/quake3/trunk@1642 edf5b092-35ff-0310-97b2-ce42778d08ea
-rw-r--r--code/client/cl_keys.c239
1 files changed, 103 insertions, 136 deletions
diff --git a/code/client/cl_keys.c b/code/client/cl_keys.c
index f2932d9..b6eb208 100644
--- a/code/client/cl_keys.c
+++ b/code/client/cl_keys.c
@@ -1118,94 +1118,72 @@ void CL_InitKeyCommands( void ) {
/*
===================
-CL_AddKeyUpCommands
+CL_ParseBinding
+
+Execute the commands in the bind string
===================
*/
-void CL_AddKeyUpCommands( int key, char *kb, unsigned time) {
- int i;
- char button[1024], *buttonPtr;
- char cmd[1024];
- qboolean keyevent;
+void CL_ParseBinding( int key, qboolean down, unsigned time )
+{
+ char buf[ MAX_STRING_CHARS ], *p = buf, *end;
- if ( !kb ) {
+ if( !keys[key].binding || !keys[key].binding[0] )
return;
- }
- keyevent = qfalse;
- buttonPtr = button;
- for ( i = 0; ; i++ ) {
- if ( kb[i] == ';' || !kb[i] ) {
- *buttonPtr = '\0';
- if ( button[0] == '+') {
- // button commands add keynum and time as parms so that multiple
- // sources can be discriminated and subframe corrected
- Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", button+1, key, time);
- Cbuf_AddText (cmd);
- keyevent = qtrue;
- } else {
- if (keyevent) {
- // down-only command
- Cbuf_AddText (button);
- Cbuf_AddText ("\n");
- }
- }
- buttonPtr = button;
- while ( (kb[i] <= ' ' || kb[i] == ';') && kb[i] != 0 ) {
- i++;
- }
+ Q_strncpyz( buf, keys[key].binding, sizeof( buf ) );
+
+ while( 1 )
+ {
+ while( isspace( *p ) )
+ p++;
+ end = strchr( p, ';' );
+ if( end )
+ *end = '\0';
+ if( *p == '+' )
+ {
+ // button commands add keynum and time as parameters
+ // so that multiple sources can be discriminated and
+ // subframe corrected
+ char cmd[1024];
+ Com_sprintf( cmd, sizeof( cmd ), "%c%s %d %d\n",
+ ( down ) ? '+' : '-', p + 1, key, time );
+ Cbuf_AddText( cmd );
}
- *buttonPtr++ = kb[i];
- if ( !kb[i] ) {
- break;
+ else if( down )
+ {
+ // normal commands only execute on key press
+ Cbuf_AddText( p );
+ Cbuf_AddText( "\n" );
}
+ if( !end )
+ break;
+ p = end + 1;
}
}
/*
===================
-CL_KeyEvent
+CL_KeyDownEvent
-Called by the system for both key up and key down events
+Called by CL_KeyEvent to handle a keypress
===================
*/
-void CL_KeyEvent (int key, qboolean down, unsigned time) {
- char *kb;
- char cmd[1024];
-
- // update auto-repeat status and BUTTON_ANY status
- keys[key].down = down;
-
- if (down) {
- keys[key].repeats++;
- if ( keys[key].repeats == 1) {
- anykeydown++;
- }
- } else {
- keys[key].repeats = 0;
- anykeydown--;
- if (anykeydown < 0) {
- anykeydown = 0;
- }
- }
+void CL_KeyDownEvent( int key, unsigned time )
+{
+ keys[key].down = qtrue;
+ keys[key].repeats++;
+ if( keys[key].repeats == 1 )
+ anykeydown++;
- if (key == K_ENTER)
+ if( keys[K_ALT].down && key == K_ENTER )
{
- if (down)
- {
- if (keys[K_ALT].down)
- {
- Cvar_SetValue( "r_fullscreen",
- !Cvar_VariableIntegerValue( "r_fullscreen" ) );
- return;
- }
- }
+ Cvar_SetValue( "r_fullscreen",
+ !Cvar_VariableIntegerValue( "r_fullscreen" ) );
+ return;
}
// console key is hardcoded, so the user can never unbind it
- if (key == K_CONSOLE ||
- ( key == K_ESCAPE && keys[K_SHIFT].down ) ) {
- if (!down) {
- return;
- }
+ if( key == K_CONSOLE || ( keys[K_SHIFT].down && key == K_ESCAPE ) )
+ {
Con_ToggleConsole_f ();
Key_ClearStates ();
return;
@@ -1213,7 +1191,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
// keys can still be used for bound actions
- if ( down && ( key < 128 || key == K_MOUSE1 ) &&
+ if ( ( key < 128 || key == K_MOUSE1 ) &&
( clc.demoplaying || cls.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) {
if (Cvar_VariableValue ("com_cameraMode") == 0) {
@@ -1222,9 +1200,8 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
}
}
-
// escape is always handled special
- if ( key == K_ESCAPE && down ) {
+ if ( key == K_ESCAPE ) {
if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) {
// clear message mode
Message_Key( key );
@@ -1250,43 +1227,20 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
return;
}
- VM_Call( uivm, UI_KEY_EVENT, key, down );
+ VM_Call( uivm, UI_KEY_EVENT, key, qtrue );
return;
}
- //
- // key up events only perform actions if the game key binding is
- // a button command (leading + sign). These will be processed even in
- // console mode and menu mode, to keep the character from continuing
- // an action started before a mode switch.
- //
- if (!down ) {
- if ( cls.state != CA_DISCONNECTED ) {
- kb = keys[key].binding;
-
- CL_AddKeyUpCommands( key, kb, time );
- }
-
- if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) {
- VM_Call( uivm, UI_KEY_EVENT, key, down );
- } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) {
- VM_Call( cgvm, CG_KEY_EVENT, key, down );
- }
-
- return;
- }
-
-
// distribute the key down event to the apropriate handler
if ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) {
Console_Key( key );
} else if ( Key_GetCatcher( ) & KEYCATCH_UI ) {
if ( uivm ) {
- VM_Call( uivm, UI_KEY_EVENT, key, down );
+ VM_Call( uivm, UI_KEY_EVENT, key, qtrue );
}
} else if ( Key_GetCatcher( ) & KEYCATCH_CGAME ) {
if ( cgvm ) {
- VM_Call( cgvm, CG_KEY_EVENT, key, down );
+ VM_Call( cgvm, CG_KEY_EVENT, key, qtrue );
}
} else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) {
Message_Key( key );
@@ -1294,47 +1248,60 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
Console_Key( key );
} else {
// send the bound action
- kb = keys[key].binding;
- if ( !kb ) {
- if (key >= 200) {
- Com_Printf ("%s is unbound, use controls menu to set.\n"
- , Key_KeynumToString( key ) );
- }
- } else if (kb[0] == '+') {
- int i;
- char button[1024], *buttonPtr;
- buttonPtr = button;
- for ( i = 0; ; i++ ) {
- if ( kb[i] == ';' || !kb[i] ) {
- *buttonPtr = '\0';
- if ( button[0] == '+') {
- // button commands add keynum and time as parms so that multiple
- // sources can be discriminated and subframe corrected
- Com_sprintf (cmd, sizeof(cmd), "%s %i %i\n", button, key, time);
- Cbuf_AddText (cmd);
- } else {
- // down-only command
- Cbuf_AddText (button);
- Cbuf_AddText ("\n");
- }
- buttonPtr = button;
- while ( (kb[i] <= ' ' || kb[i] == ';') && kb[i] != 0 ) {
- i++;
- }
- }
- *buttonPtr++ = kb[i];
- if ( !kb[i] ) {
- break;
- }
- }
- } else {
- // down-only command
- Cbuf_AddText (kb);
- Cbuf_AddText ("\n");
- }
+ CL_ParseBinding( key, qtrue, time );
+ }
+ return;
+}
+
+/*
+===================
+CL_KeyUpEvent
+
+Called by CL_KeyEvent to handle a keyrelease
+===================
+*/
+void CL_KeyUpEvent( int key, unsigned time )
+{
+ keys[key].repeats = 0;
+ keys[key].down = qfalse;
+ anykeydown--;
+ if (anykeydown < 0) {
+ anykeydown = 0;
+ }
+
+ // don't process key-up events for the console key
+ if ( key == K_CONSOLE || ( key == K_ESCAPE && keys[K_SHIFT].down ) )
+ return;
+
+ //
+ // key up events only perform actions if the game key binding is
+ // a button command (leading + sign). These will be processed even in
+ // console mode and menu mode, to keep the character from continuing
+ // an action started before a mode switch.
+ //
+ if( cls.state != CA_DISCONNECTED )
+ CL_ParseBinding( key, qfalse, time );
+
+ if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) {
+ VM_Call( uivm, UI_KEY_EVENT, key, qfalse );
+ } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) {
+ VM_Call( cgvm, CG_KEY_EVENT, key, qfalse );
}
}
+/*
+===================
+CL_KeyEvent
+
+Called by the system for both key up and key down events
+===================
+*/
+void CL_KeyEvent (int key, qboolean down, unsigned time) {
+ if( down )
+ CL_KeyDownEvent( key, time );
+ else
+ CL_KeyUpEvent( key, time );
+}
/*
===================