|
|
1.1 root 1: #include "client.h"
2: /*
3: key up events are sent even if in console mode
4: */
5: #define MAXCMDLINE 256
6: char key_lines[32][MAXCMDLINE];
7: int key_linepos;
8: int shift_down=false;
9: qboolean anykeydown;
10: int edit_line=0;
11: int history_line=0;
12:
13: int key_waiting;
14: char *keybindings[256];
15: qboolean consolekeys[256]; // if true, can't be rebound while in console
16: qboolean menubound[256]; // if true, can't be rebound while in menu
17: int keyshift[256]; // key to map to if shift held down in console
18: int key_repeats[256]; // if > 1, it is autorepeating
19: qboolean keydown[256];
20: typedef struct
21: {
22: char *name;
23: int keynum;
24: } keyname_t;
25: keyname_t keynames[] =
26: {
27: {"TAB", K_TAB},
28: {"ENTER", K_ENTER},
29: {"ESCAPE", K_ESCAPE},
30: {"SPACE", K_SPACE},
31: {"BACKSPACE", K_BACKSPACE},
32: {"UPARROW", K_UPARROW},
33: {"DOWNARROW", K_DOWNARROW},
34: {"LEFTARROW", K_LEFTARROW},
35: {"RIGHTARROW", K_RIGHTARROW},
36: {"ALT", K_ALT},
37: {"CTRL", K_CTRL},
38: {"SHIFT", K_SHIFT},
39:
40: {"F1", K_F1},
41: {"F2", K_F2},
42: {"F3", K_F3},
43: {"F4", K_F4},
44: {"F5", K_F5},
45: {"F6", K_F6},
46: {"F7", K_F7},
47: {"F8", K_F8},
48: {"F9", K_F9},
49: {"F10", K_F10},
50: {"F11", K_F11},
51: {"F12", K_F12},
52: {"INS", K_INS},
53: {"DEL", K_DEL},
54: {"PGDN", K_PGDN},
55: {"PGUP", K_PGUP},
56: {"HOME", K_HOME},
57: {"END", K_END},
58: {"MOUSE1", K_MOUSE1},
59: {"MOUSE2", K_MOUSE2},
60: {"MOUSE3", K_MOUSE3},
61:
62: {"JOY1", K_JOY1},
63: {"JOY2", K_JOY2},
64: {"JOY3", K_JOY3},
65: {"JOY4", K_JOY4},
66: {"AUX1", K_AUX1},
67: {"AUX2", K_AUX2},
68: {"AUX3", K_AUX3},
69: {"AUX4", K_AUX4},
70: {"AUX5", K_AUX5},
71: {"AUX6", K_AUX6},
72: {"AUX7", K_AUX7},
73: {"AUX8", K_AUX8},
74: {"AUX9", K_AUX9},
75: {"AUX10", K_AUX10},
76: {"AUX11", K_AUX11},
77: {"AUX12", K_AUX12},
78: {"AUX13", K_AUX13},
79: {"AUX14", K_AUX14},
80: {"AUX15", K_AUX15},
81: {"AUX16", K_AUX16},
82: {"AUX17", K_AUX17},
83: {"AUX18", K_AUX18},
84: {"AUX19", K_AUX19},
85: {"AUX20", K_AUX20},
86: {"AUX21", K_AUX21},
87: {"AUX22", K_AUX22},
88: {"AUX23", K_AUX23},
89: {"AUX24", K_AUX24},
90: {"AUX25", K_AUX25},
91: {"AUX26", K_AUX26},
92: {"AUX27", K_AUX27},
93: {"AUX28", K_AUX28},
94: {"AUX29", K_AUX29},
95: {"AUX30", K_AUX30},
96: {"AUX31", K_AUX31},
97: {"AUX32", K_AUX32},
98:
99: {"KP_HOME", K_KP_HOME },
100: {"KP_UPARROW", K_KP_UPARROW },
101: {"KP_PGUP", K_KP_PGUP },
102: {"KP_LEFTARROW", K_KP_LEFTARROW },
103: {"KP_5", K_KP_5 },
104: {"KP_RIGHTARROW", K_KP_RIGHTARROW },
105: {"KP_END", K_KP_END },
106: {"KP_DOWNARROW", K_KP_DOWNARROW },
107: {"KP_PGDN", K_KP_PGDN },
108: {"KP_ENTER", K_KP_ENTER },
109: {"KP_INS", K_KP_INS },
110: {"KP_DEL", K_KP_DEL },
111: {"KP_SLASH", K_KP_SLASH },
112: {"KP_MINUS", K_KP_MINUS },
113: {"KP_PLUS", K_KP_PLUS },
114:
115: {"MWHEELUP", K_MWHEELUP },
116: {"MWHEELDOWN", K_MWHEELDOWN },
117:
118: {"PAUSE", K_PAUSE},
119: {"SEMICOLON", ';'}, // because a raw semicolon seperates commands
120: {NULL,0}
121: };
122: /*
123: ==============================================================================
124: LINE TYPING INTO THE CONSOLE
125: ==============================================================================
126: */
127: void CompleteCommand (void)
128: {
129: char *cmd, *s;
130: s = key_lines[edit_line]+1;
131: if (*s == '\\' || *s == '/')
132: s++;
133: cmd = Cmd_CompleteCommand (s);
134: if (!cmd)
135: cmd = Cvar_CompleteVariable (s);
136: if (cmd)
137: {
138: key_lines[edit_line][1] = '/';
139: strcpy (key_lines[edit_line]+2, cmd);
140: key_linepos = strlen(cmd)+2;
141: key_lines[edit_line][key_linepos] = ' ';
142: key_linepos++;
143: key_lines[edit_line][key_linepos] = 0;
144: return;
145: }
146: }
147: /*
148: ====================
149: Key_Console
150: Interactive line editing and console scrollback
151: ====================
152: */
153: void Key_Console (int key)
154: {
155:
156: switch ( key )
157: {
158: case K_KP_SLASH:
159: key = '/';
160: break;
161: case K_KP_MINUS:
162: key = '-';
163: break;
164: case K_KP_PLUS:
165: key = '+';
166: break;
167: case K_KP_HOME:
168: key = '7';
169: break;
170: case K_KP_UPARROW:
171: key = '8';
172: break;
173: case K_KP_PGUP:
174: key = '9';
175: break;
176: case K_KP_LEFTARROW:
177: key = '4';
178: break;
179: case K_KP_5:
180: key = '5';
181: break;
182: case K_KP_RIGHTARROW:
183: key = '6';
184: break;
185: case K_KP_END:
186: key = '1';
187: break;
188: case K_KP_DOWNARROW:
189: key = '2';
190: break;
191: case K_KP_PGDN:
192: key = '3';
193: break;
194: case K_KP_INS:
195: key = '0';
196: break;
197: case K_KP_DEL:
198: key = '.';
199: break;
200: }
201:
202: if ( ( toupper( key ) == 'V' && keydown[K_CTRL] ) ||
203: ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) )
204: {
205: char *cbd;
206:
207: if ( ( cbd = Sys_GetClipboardData() ) != 0 )
208: {
209: int i;
210:
211: strtok( cbd, "\n\r\b" );
212:
213: i = strlen( cbd );
214: if ( i + key_linepos >= MAXCMDLINE)
215: i= MAXCMDLINE - key_linepos;
216:
217: if ( i > 0 )
218: {
219: cbd[i]=0;
220: strcat( key_lines[edit_line], cbd );
221: key_linepos += i;
222: }
223: free( cbd );
224: }
225:
226: return;
227: }
228:
229: if ( key == 'l' )
230: {
231: if ( keydown[K_CTRL] )
232: {
233: Cbuf_AddText ("clear\n");
234: return;
235: }
236: }
237: if ( key == K_ENTER || key == K_KP_ENTER )
238: { // backslash text are commands, else chat
239: if (key_lines[edit_line][1] == '\\' || key_lines[edit_line][1] == '/')
240: Cbuf_AddText (key_lines[edit_line]+2); // skip the >
241: else
242: Cbuf_AddText (key_lines[edit_line]+1); // valid command
243: Cbuf_AddText ("\n");
244: Com_Printf ("%s\n",key_lines[edit_line]);
245: edit_line = (edit_line + 1) & 31;
246: history_line = edit_line;
247: key_lines[edit_line][0] = ']';
248: key_linepos = 1;
249: if (cls.state == ca_disconnected)
250: SCR_UpdateScreen (); // force an update, because the command
251: // may take some time
252: return;
253: }
254: if (key == K_TAB)
255: { // command completion
256: CompleteCommand ();
257: return;
258: }
259:
260: if ( ( key == K_BACKSPACE ) || ( key == K_LEFTARROW ) || ( key == K_KP_LEFTARROW ) || ( ( key == 'h' ) && ( keydown[K_CTRL] ) ) )
261: {
262: if (key_linepos > 1)
263: key_linepos--;
264: return;
265: }
266: if ( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ||
267: ( ( key == 'p' ) && keydown[K_CTRL] ) )
268: {
269: do
270: {
271: history_line = (history_line - 1) & 31;
272: } while (history_line != edit_line
273: && !key_lines[history_line][1]);
274: if (history_line == edit_line)
275: history_line = (edit_line+1)&31;
276: strcpy(key_lines[edit_line], key_lines[history_line]);
277: key_linepos = strlen(key_lines[edit_line]);
278: return;
279: }
280: if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ||
281: ( ( key == 'n' ) && keydown[K_CTRL] ) )
282: {
283: if (history_line == edit_line) return;
284: do
285: {
286: history_line = (history_line + 1) & 31;
287: }
288: while (history_line != edit_line
289: && !key_lines[history_line][1]);
290: if (history_line == edit_line)
291: {
292: key_lines[edit_line][0] = ']';
293: key_linepos = 1;
294: }
295: else
296: {
297: strcpy(key_lines[edit_line], key_lines[history_line]);
298: key_linepos = strlen(key_lines[edit_line]);
299: }
300: return;
301: }
302: if (key == K_PGUP || key == K_KP_PGUP )
303: {
304: con.display -= 2;
305: return;
306: }
307: if (key == K_PGDN || key == K_KP_PGDN )
308: {
309: con.display += 2;
310: if (con.display > con.current)
311: con.display = con.current;
312: return;
313: }
314: if (key == K_HOME || key == K_KP_HOME )
315: {
316: con.display = con.current - con.totallines + 10;
317: return;
318: }
319: if (key == K_END || key == K_KP_END )
320: {
321: con.display = con.current;
322: return;
323: }
324:
325: if (key < 32 || key > 127)
326: return; // non printable
327:
328: if (key_linepos < MAXCMDLINE-1)
329: {
330: key_lines[edit_line][key_linepos] = key;
331: key_linepos++;
332: key_lines[edit_line][key_linepos] = 0;
333: }
334: }
335: //============================================================================
336: qboolean chat_team;
337: char chat_buffer[MAXCMDLINE];
338: int chat_bufferlen = 0;
339: void Key_Message (int key)
340: {
341: if ( key == K_ENTER || key == K_KP_ENTER )
342: {
343: if (chat_team)
344: Cbuf_AddText ("say_team \"");
345: else
346: Cbuf_AddText ("say \"");
347: Cbuf_AddText(chat_buffer);
348: Cbuf_AddText("\"\n");
349: cls.key_dest = key_game;
350: chat_bufferlen = 0;
351: chat_buffer[0] = 0;
352: return;
353: }
354: if (key == K_ESCAPE)
355: {
356: cls.key_dest = key_game;
357: chat_bufferlen = 0;
358: chat_buffer[0] = 0;
359: return;
360: }
361: if (key < 32 || key > 127)
362: return; // non printable
363: if (key == K_BACKSPACE)
364: {
365: if (chat_bufferlen)
366: {
367: chat_bufferlen--;
368: chat_buffer[chat_bufferlen] = 0;
369: }
370: return;
371: }
372: if (chat_bufferlen == sizeof(chat_buffer)-1)
373: return; // all full
374: chat_buffer[chat_bufferlen++] = key;
375: chat_buffer[chat_bufferlen] = 0;
376: }
377: //============================================================================
378: /*
379: ===================
380: Key_StringToKeynum
381: Returns a key number to be used to index keybindings[] by looking at
382: the given string. Single ascii characters return themselves, while
383: the K_* names are matched up.
384: ===================
385: */
386: int Key_StringToKeynum (char *str)
387: {
388: keyname_t *kn;
389:
390: if (!str || !str[0])
391: return -1;
392: if (!str[1])
393: return str[0];
394: for (kn=keynames ; kn->name ; kn++)
395: {
396: if (!Q_strcasecmp(str,kn->name))
397: return kn->keynum;
398: }
399: return -1;
400: }
401: /*
402: ===================
403: Key_KeynumToString
404: Returns a string (either a single ascii char, or a K_* name) for the
405: given keynum.
406: FIXME: handle quote special (general escape sequence?)
407: ===================
408: */
409: char *Key_KeynumToString (int keynum)
410: {
411: keyname_t *kn;
412: static char tinystr[2];
413:
414: if (keynum == -1)
415: return "<KEY NOT FOUND>";
416: if (keynum > 32 && keynum < 127)
417: { // printable ascii
418: tinystr[0] = keynum;
419: tinystr[1] = 0;
420: return tinystr;
421: }
422:
423: for (kn=keynames ; kn->name ; kn++)
424: if (keynum == kn->keynum)
425: return kn->name;
426: return "<UNKNOWN KEYNUM>";
427: }
428: /*
429: ===================
430: Key_SetBinding
431: ===================
432: */
433: void Key_SetBinding (int keynum, char *binding)
434: {
435: char *new;
436: int l;
437:
438: if (keynum == -1)
439: return;
440: // free old bindings
441: if (keybindings[keynum])
442: {
443: Z_Free (keybindings[keynum]);
444: keybindings[keynum] = NULL;
445: }
446:
447: // allocate memory for new binding
448: l = strlen (binding);
449: new = Z_Malloc (l+1);
450: strcpy (new, binding);
451: new[l] = 0;
452: keybindings[keynum] = new;
453: }
454: /*
455: ===================
456: Key_Unbind_f
457: ===================
458: */
459: void Key_Unbind_f (void)
460: {
461: int b;
462: if (Cmd_Argc() != 2)
463: {
464: Com_Printf ("unbind <key> : remove commands from a key\n");
465: return;
466: }
467:
468: b = Key_StringToKeynum (Cmd_Argv(1));
469: if (b==-1)
470: {
471: Com_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
472: return;
473: }
474: Key_SetBinding (b, "");
475: }
476: void Key_Unbindall_f (void)
477: {
478: int i;
479:
480: for (i=0 ; i<256 ; i++)
481: if (keybindings[i])
482: Key_SetBinding (i, "");
483: }
484: /*
485: ===================
486: Key_Bind_f
487: ===================
488: */
489: void Key_Bind_f (void)
490: {
491: int i, c, b;
492: char cmd[1024];
493:
494: c = Cmd_Argc();
495: if (c < 2)
496: {
497: Com_Printf ("bind <key> [command] : attach a command to a key\n");
498: return;
499: }
500: b = Key_StringToKeynum (Cmd_Argv(1));
501: if (b==-1)
502: {
503: Com_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
504: return;
505: }
506: if (c == 2)
507: {
508: if (keybindings[b])
509: Com_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] );
510: else
511: Com_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
512: return;
513: }
514:
515: // copy the rest of the command line
516: cmd[0] = 0; // start out with a null string
517: for (i=2 ; i< c ; i++)
518: {
519: strcat (cmd, Cmd_Argv(i));
520: if (i != (c-1))
521: strcat (cmd, " ");
522: }
523: Key_SetBinding (b, cmd);
524: }
525: /*
526: ============
527: Key_WriteBindings
528: Writes lines containing "bind key value"
529: ============
530: */
531: void Key_WriteBindings (FILE *f)
532: {
533: int i;
534: for (i=0 ; i<256 ; i++)
535: if (keybindings[i] && keybindings[i][0])
536: fprintf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
537: }
538: /*
539: ============
540: Key_Bindlist_f
541: ============
542: */
543: void Key_Bindlist_f (void)
544: {
545: int i;
546: for (i=0 ; i<256 ; i++)
547: if (keybindings[i] && keybindings[i][0])
548: Com_Printf ("%s \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
549: }
550: /*
551: ===================
552: Key_Init
553: ===================
554: */
555: void Key_Init (void)
556: {
557: int i;
558: for (i=0 ; i<32 ; i++)
559: {
560: key_lines[i][0] = ']';
561: key_lines[i][1] = 0;
562: }
563: key_linepos = 1;
564:
565: //
566: // init ascii characters in console mode
567: //
568: for (i=32 ; i<128 ; i++)
569: consolekeys[i] = true;
570: consolekeys[K_ENTER] = true;
571: consolekeys[K_KP_ENTER] = true;
572: consolekeys[K_TAB] = true;
573: consolekeys[K_LEFTARROW] = true;
574: consolekeys[K_KP_LEFTARROW] = true;
575: consolekeys[K_RIGHTARROW] = true;
576: consolekeys[K_KP_RIGHTARROW] = true;
577: consolekeys[K_UPARROW] = true;
578: consolekeys[K_KP_UPARROW] = true;
579: consolekeys[K_DOWNARROW] = true;
580: consolekeys[K_KP_DOWNARROW] = true;
581: consolekeys[K_BACKSPACE] = true;
582: consolekeys[K_HOME] = true;
583: consolekeys[K_KP_HOME] = true;
584: consolekeys[K_END] = true;
585: consolekeys[K_KP_END] = true;
586: consolekeys[K_PGUP] = true;
587: consolekeys[K_KP_PGUP] = true;
588: consolekeys[K_PGDN] = true;
589: consolekeys[K_KP_PGDN] = true;
590: consolekeys[K_SHIFT] = true;
591: consolekeys[K_INS] = true;
592: consolekeys[K_KP_INS] = true;
593: consolekeys[K_KP_DEL] = true;
594: consolekeys[K_KP_SLASH] = true;
595: consolekeys[K_KP_PLUS] = true;
596: consolekeys[K_KP_MINUS] = true;
597: consolekeys[K_KP_5] = true;
598:
599: consolekeys['`'] = false;
600: consolekeys['~'] = false;
601: for (i=0 ; i<256 ; i++)
602: keyshift[i] = i;
603: for (i='a' ; i<='z' ; i++)
604: keyshift[i] = i - 'a' + 'A';
605: keyshift['1'] = '!';
606: keyshift['2'] = '@';
607: keyshift['3'] = '#';
608: keyshift['4'] = '$';
609: keyshift['5'] = '%';
610: keyshift['6'] = '^';
611: keyshift['7'] = '&';
612: keyshift['8'] = '*';
613: keyshift['9'] = '(';
614: keyshift['0'] = ')';
615: keyshift['-'] = '_';
616: keyshift['='] = '+';
617: keyshift[','] = '<';
618: keyshift['.'] = '>';
619: keyshift['/'] = '?';
620: keyshift[';'] = ':';
621: keyshift['\''] = '"';
622: keyshift['['] = '{';
623: keyshift[']'] = '}';
624: keyshift['`'] = '~';
625: keyshift['\\'] = '|';
626: menubound[K_ESCAPE] = true;
627: for (i=0 ; i<12 ; i++)
628: menubound[K_F1+i] = true;
629: //
630: // register our functions
631: //
632: Cmd_AddCommand ("bind",Key_Bind_f);
633: Cmd_AddCommand ("unbind",Key_Unbind_f);
634: Cmd_AddCommand ("unbindall",Key_Unbindall_f);
635: Cmd_AddCommand ("bindlist",Key_Bindlist_f);
636: }
637: /*
638: ===================
639: Key_Event
640: Called by the system between frames for both key up and key down events
641: Should NOT be called during an interrupt!
642: ===================
643: */
644: void Key_Event (int key, qboolean down, unsigned time)
645: {
646: char *kb;
647: char cmd[1024];
648:
649: // hack for modal presses
650: if (key_waiting == -1)
651: {
652: if (down)
653: key_waiting = key;
654: return;
655: }
656: // update auto-repeat status
657: if (down)
658: {
659: key_repeats[key]++;
660: if (key != K_BACKSPACE
661: && key != K_PAUSE
662: && key != K_PGUP
663: && key != K_KP_PGUP
664: && key != K_PGDN
665: && key != K_KP_PGDN
666: && key_repeats[key] > 1)
667: return; // ignore most autorepeats
668:
669: if (key >= 200 && !keybindings[key])
670: Com_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) );
671: }
672: else
673: {
674: key_repeats[key] = 0;
675: }
676: if (key == K_SHIFT)
677: shift_down = down;
678: // console key is hardcoded, so the user can never unbind it
679: if (key == '`' || key == '~')
680: {
681: if (!down)
682: return;
683: Con_ToggleConsole_f ();
684: return;
685: }
686: // any key during the attract mode will bring up the menu
687: if (cl.attractloop && cls.key_dest != key_menu)
688: key = K_ESCAPE;
689: // menu key is hardcoded, so the user can never unbind it
690: if (key == K_ESCAPE)
691: {
692: if (!down)
693: return;
694: if (cl.frame.playerstate.stats[STAT_LAYOUTS] && cls.key_dest == key_game)
695: { // put away help computer / inventory
696: Cbuf_AddText ("cmd putaway\n");
697: return;
698: }
699: switch (cls.key_dest)
700: {
701: case key_message:
702: Key_Message (key);
703: break;
704: case key_menu:
705: M_Keydown (key);
706: break;
707: case key_game:
708: case key_console:
709: M_Menu_Main_f ();
710: break;
711: default:
712: Com_Error (ERR_FATAL, "Bad cls.key_dest");
713: }
714: return;
715: }
716: // track if any key is down for BUTTON_ANY
717: keydown[key] = down;
718: if (down)
719: {
720: if (key_repeats[key] == 1)
721: anykeydown++;
722: }
723: else
724: {
725: anykeydown--;
726: if (anykeydown < 0)
727: anykeydown = 0;
728: }
729: //
730: // key up events only generate commands if the game key binding is
731: // a button command (leading + sign). These will occur even in console mode,
732: // to keep the character from continuing an action started before a console
733: // switch. Button commands include the kenum as a parameter, so multiple
734: // downs can be matched with ups
735: //
736: if (!down)
737: {
738: kb = keybindings[key];
739: if (kb && kb[0] == '+')
740: {
741: Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time);
742: Cbuf_AddText (cmd);
743: }
744: if (keyshift[key] != key)
745: {
746: kb = keybindings[keyshift[key]];
747: if (kb && kb[0] == '+')
748: {
749: Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", kb+1, key, time);
750: Cbuf_AddText (cmd);
751: }
752: }
753: return;
754: }
755: //
756: // if not a consolekey, send to the interpreter no matter what mode is
757: //
758: if ( (cls.key_dest == key_menu && menubound[key])
759: || (cls.key_dest == key_console && !consolekeys[key])
760: || (cls.key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) )
761: {
762: kb = keybindings[key];
763: if (kb)
764: {
765: if (kb[0] == '+')
766: { // button commands add keynum and time as a parm
767: Com_sprintf (cmd, sizeof(cmd), "%s %i %i\n", kb, key, time);
768: Cbuf_AddText (cmd);
769: }
770: else
771: {
772: Cbuf_AddText (kb);
773: Cbuf_AddText ("\n");
774: }
775: }
776: return;
777: }
778: if (!down)
779: return; // other systems only care about key down events
780: if (shift_down)
781: key = keyshift[key];
782:
783: switch (cls.key_dest)
784: {
785: case key_message:
786: Key_Message (key);
787: break;
788: case key_menu:
789: M_Keydown (key);
790: break;
791: case key_game:
792: case key_console:
793: Key_Console (key);
794: break;
795: default:
796: Com_Error (ERR_FATAL, "Bad cls.key_dest");
797: }
798: }
799: /*
800: ===================
801: Key_ClearStates
802: ===================
803: */
804: void Key_ClearStates (void)
805: {
806: int i;
807: anykeydown = false;
808: for (i=0 ; i<256 ; i++)
809: {
810: if ( keydown[i] || key_repeats[i] )
811: Key_Event( i, false, 0 );
812: keydown[i] = 0;
813: key_repeats[i] = 0;
814: }
815: }
816:
817: /*
818: ===================
819: Key_GetKey
820: ===================
821: */
822: int Key_GetKey (void)
823: {
824: key_waiting = -1;
825:
826: while (key_waiting == -1)
827: Sys_SendKeyEvents ();
828:
829: return key_waiting;
830: }
831:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.