mirror of
https://github.com/UberGames/ioef.git
synced 2024-11-30 16:01:46 +00:00
Rewrite of key event processing, thanks to /dev/humancontroller and Ben Millwood. https://bugzilla.icculus.org/show_bug.cgi?id=3374
This commit is contained in:
parent
3a952ff196
commit
dd572db7d6
1 changed files with 103 additions and 136 deletions
|
@ -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] ) {
|
||||
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];
|
||||
void CL_KeyDownEvent( int key, unsigned time )
|
||||
{
|
||||
keys[key].down = qtrue;
|
||||
keys[key].repeats++;
|
||||
if( keys[key].repeats == 1 )
|
||||
anykeydown++;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
|
|
Loading…
Reference in a new issue