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