/* ============== CL_StopPlayback Called when a demo file runs out, or the user starts a game ============== */ void CL_StopPlayback (void) { if (!cls.demoplayback) return; if (intro_playing) M_ToggleMenu_f(); intro_playing=false; num_intro_msg=0; fclose (cls.demofile); cls.demoplayback = false; cls.demofile = NULL; cls.state = ca_disconnected; if (cls.timedemo) CL_FinishTimeDemo (); }
/* =================== 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"); } }