/* =================== Key_Event Called by the system between frames for both key up and key down events Should NOT be called during an interrupt! =================== */ void Key_Event (int key, qboolean down) { char *kb; char cmd[1024]; keydown[key] = down; if (!down) key_repeats[key] = 0; key_lastpress = key; key_count++; if (key_count <= 0) return; // just catching keys for Con_NotifyBox // update auto-repeat status if (down) { /* Pause key doesn't generate a scancode when released, * never increment its auto-repeat status. */ if (key != K_PAUSE && key != K_KP_NUMLOCK) key_repeats[key]++; #if 0 if (key != K_BACKSPACE && key != K_PGUP && key != K_PGDN && key_repeats[key] > 1) return; // ignore most autorepeats #endif if (key_repeats[key] > 1) { if (key_dest == key_game && !con_forcedup) return; // ignore autorepeats in game mode } else if (key >= 200 && !keybindings[key]) Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString(key)); } if (key == K_SHIFT) shift_down = down; // handle escape specialy, so the user can never unbind it if (key == K_ESCAPE) { if (!down) return; switch (key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_menubind: M_Keybind (key); break; case key_game: case key_console: M_ToggleMenu_f (); break; default: Sys_Error ("Bad key_dest"); } return; } // key up events only generate commands if the game key binding is // a button command (leading + sign). These will occur even in console mode, // to keep the character from continuing an action started before a console // switch. Button commands include the kenum as a parameter, so multiple // downs can be matched with ups if (!down) { kb = keybindings[key]; if (kb && kb[0] == '+') { sprintf (cmd, "-%s %i\n", kb+1, key); Cbuf_AddText (cmd); } if (keyshift[key] != key) { kb = keybindings[keyshift[key]]; if (kb && kb[0] == '+') { sprintf (cmd, "-%s %i\n", kb+1, key); Cbuf_AddText (cmd); } } return; } // during demo playback, most keys bring up the main menu if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) { M_ToggleMenu_f (); return; } // if not a consolekey, send to the interpreter no matter what mode is if (((key_dest & key_menu) && menubound[key]) || (key_dest == key_console && !consolekeys[key]) || (key_dest == key_game && (!con_forcedup || !consolekeys[key]))) { kb = keybindings[key]; if (kb) { if (kb[0] == '+') { // button commands add keynum as a parm sprintf (cmd, "%s %i\n", kb, key); Cbuf_AddText (cmd); } else { Cbuf_AddText (kb); Cbuf_AddText ("\n"); } } return; } if (!down) return; // other systems only care about key down events if (shift_down) key = keyshift[key]; switch (key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_menubind: M_Keybind (key); break; case key_game: case key_console: Key_Console (key); break; default: Sys_Error ("Bad key_dest"); } }
/* =================== Key_Event Called by the system between frames for both key up and key down events Should NOT be called during an interrupt! =================== */ void Key_Event (int key, qboolean down, uint32 time) { char *kb; char cmd[1024]; // hack for modal presses /*if (key_waiting == -1) { if (down) key_waiting = key; return; }*/ //Com_Printf ("%d is %d for %u\n", LOG_GENERAL, key, down, time); // update auto-repeat status if (down) { key_repeats[key]++; if (cls.key_dest != key_console && key != K_BACKSPACE && key != K_DEL && key != K_LEFTARROW && key != K_RIGHTARROW && key != K_PAUSE && key != K_PGUP && key != K_KP_PGUP && key != K_PGDN && key != K_KP_PGDN && key_repeats[key] > 1) return; // ignore most autorepeats if (key >= 200 && !keybindings[key]) Com_Printf ("%s is unbound, hit F4 to set.\n", LOG_CLIENT, Key_KeynumToString (key) ); } else { key_repeats[key] = 0; } //for dinput if (down && keydown[K_ALT]) { if (key == K_ENTER) { Com_Printf ("ALT+Enter, setting fullscreen %d.\n", LOG_CLIENT, !vid_fullscreen->intvalue); Cvar_SetValue( "vid_fullscreen", (float)!vid_fullscreen->intvalue ); return; } else if (key == K_TAB) { //prevent executing action on alt+tab return; } } if (key == K_SHIFT) shift_down = down; // console key is hardcoded, so the user can never unbind it if ((key == '`' || key == '~') && !shift_down) { if (!down) return; Con_ToggleConsole_f (); return; } // any key during the attract mode will bring up the menu /*if (cl.attractloop && cls.key_dest != key_menu && !(key >= K_F1 && key <= K_F12)) key = K_ESCAPE;*/ // menu key is hardcoded, so the user can never unbind it if (key == K_ESCAPE) { if (!down) return; if (cl.frame.playerstate.stats[STAT_LAYOUTS] && cls.key_dest == key_game) { // put away help computer / inventory Cbuf_AddText ("cmd putaway\n"); return; } switch (cls.key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_game: case key_console: M_Menu_Main_f (); break; default: Com_Error (ERR_FATAL, "Bad cls.key_dest"); } return; } if (!keydown[key]) key_lastrepeat[key] = curtime + key_repeatdelay; // track if any key is down for BUTTON_ANY keydown[key] = down; if (down) { if (key_repeats[key] == 1) anykeydown++; } else { key_lastrepeat[key] = 0; anykeydown--; if (anykeydown < 0) anykeydown = 0; } // // key up events only generate commands if the game key binding is // a button command (leading + sign). These will occur even in console mode, // to keep the character from continuing an action started before a console // switch. Button commands include the kenum as a parameter, so multiple // downs can be matched with ups // if (!down) { //r1ch: only generate -events if key was down (prevents -binds in menu / messagemode) if (buttondown[key]) { kb = keybindings[key]; if (kb && kb[0] == '+') { Com_sprintf (cmd, sizeof(cmd), "-%s %i %u\n", kb+1, key, time); Cbuf_AddText (cmd); } if (keyshift[key] != key) { kb = keybindings[keyshift[key]]; if (kb && kb[0] == '+') { Com_sprintf (cmd, sizeof(cmd), "-%s %i %u\n", kb+1, key, time); Cbuf_AddText (cmd); } } buttondown[key] = false; } return; } // // if not a consolekey, send to the interpreter no matter what mode is // if ( (cls.key_dest == key_menu && menubound[key]) || (cls.key_dest == key_console && !consolekeys[key]) || (cls.key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) ) { kb = keybindings[key]; if (kb && kb[0]) { if (kb[0] == '+') { // button commands add keynum and time as a parm if (cls.key_dest != key_game) //r1: don't run buttons in console return; Com_sprintf (cmd, sizeof(cmd), "%s %i %u\n", kb, key, time); Cbuf_AddText (cmd); buttondown[key] = true; } else { Cbuf_AddText (kb); Cbuf_AddText ("\n"); } } return; } //if (!down) // return; // other systems only care about key down events if (shift_down) key = keyshift[key]; switch (cls.key_dest) { case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_game: case key_console: Key_Console (key); break; default: Com_Error (ERR_FATAL, "Bad cls.key_dest"); } }
/** * \brief Called by the system between frames for both key up and key down events. * \param[in] key Key mapping * \param[in] down Is key being pressed? * \param[in] time * \note Should NOT be called during an interrupt! */ PUBLIC void Key_Event( int key, _boolean down, unsigned time ) { char *kb; char cmd[ 1024 ]; // hack for modal presses if (key_waiting == -1) { if (down) { key_waiting = key; } return; } // update auto-repeat status if (down) { key_repeats[key]++; if (key != K_BACKSPACE && key != K_PAUSE && key != K_PGUP && key != K_KP_PGUP && key != K_PGDN && key != K_KP_PGDN && key_repeats[key] > 1) { return; // ignore most autorepeats } if (key >= 200 && !keybindings[key]) { Com_Printf ( "%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) ); } } else { key_repeats[ key ] = 0; } if( key == K_SHIFT ) { shift_down = down; } // console key is hardcoded, so the user can never unbind it if( key == '`' || key == '~' ) { if( ! down ) { return; } Con_ToggleConsole_f(); return; } // any key during the attract mode will bring up the menu // if (cl.attractloop && ClientStatic.key_dest != key_menu && // !(key >= K_F1 && key <= K_F12)) // key = K_ESCAPE; // menu key is hardcoded, so the user can never unbind it if( key == K_ESCAPE ) { if( ! down ) { return; } // if (cl.frame.playerstate.stats[STAT_LAYOUTS] && ClientStatic.key_dest == key_game) // { // put away help computer / inventory // Cbuf_AddText ("cmd putaway\n"); // return; // } switch( ClientStatic.key_dest ) { case key_message: Key_Message( key ); break; case KEY_AUTOMAP: automap_keydown( key ); break; case key_menu: M_Keydown( key ); break; case key_game: case key_console: M_Menu_Main_f(); break; default: Com_DPrintf( "Bad ClientStatic.key_dest\n" ); } return; } // track if any key is down for BUTTON_ANY keydown[key] = down; if (down) { if (key_repeats[key] == 1) { anykeydown++; } } else { anykeydown--; if (anykeydown < 0) { anykeydown = 0; } } // // key up events only generate commands if the game key binding is // a button command (leading + sign). These will occur even in console mode, // to keep the character from continuing an action started before a console // switch. Button commands include the kenum as a parameter, so multiple // downs can be matched with ups // if( ! down ) { kb = keybindings[key]; if (kb && kb[0] == '+') { com_snprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time); Cbuf_AddText (cmd); } if (keyshift[key] != key) { kb = keybindings[keyshift[key]]; if (kb && kb[0] == '+') { com_snprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time); Cbuf_AddText (cmd); } } return; } // // if not a consolekey, send to the interpreter no matter what mode is // if ( (ClientStatic.key_dest == key_menu && menubound[key]) || (ClientStatic.key_dest == key_console && !consolekeys[key]) || (ClientStatic.key_dest == key_game ) ) { kb = keybindings[key]; if (kb) { if (kb[0] == '+') { // button commands add keynum and time as a parm com_snprintf (cmd, sizeof(cmd), "%s %i %i\n", kb, key, time); Cbuf_AddText (cmd); } else { Cbuf_AddText (kb); Cbuf_AddText ("\n"); } } return; } if( ! down ) { return; // other systems only care about key down events } if (shift_down) { key = keyshift[ key ]; } switch (ClientStatic.key_dest) { case KEY_AUTOMAP: automap_keydown( key ); break; case key_message: Key_Message (key); break; case key_menu: M_Keydown (key); break; case key_game: case key_console: Key_Console (key); break; default: Com_DPrintf( "Bad ClientStatic.key_dest\n" ); } }