]> icculus.org git repositories - btb/d2x.git/blob - arch/sdl/key.c
refine bind cmd
[btb/d2x.git] / arch / sdl / key.c
1 /*
2  *
3  * SDL keyboard input support
4  *
5  *
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <conf.h>
10 #endif
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include <SDL.h>
16
17 #include "inferno.h"
18 #include "game.h"
19 #include "event.h"
20 #include "error.h"
21 #include "key.h"
22 #include "timer.h"
23 #include "console.h"
24 #include "u_mem.h"
25
26
27 #define KEY_BUFFER_SIZE 16
28
29 static unsigned char Installed = 0;
30
31 //-------- Variable accessed by outside functions ---------
32 unsigned char           keyd_buffer_type;               // 0=No buffer, 1=buffer ASCII, 2=buffer scans
33 unsigned char           keyd_repeat;
34 unsigned char           keyd_editor_mode;
35 volatile unsigned char  keyd_last_pressed;
36 volatile unsigned char  keyd_last_released;
37 volatile unsigned char  keyd_pressed[256];
38 volatile int            keyd_time_when_last_pressed;
39
40 typedef struct Key_info {
41         ubyte           state;                  // state of key 1 == down, 0 == up
42         ubyte           last_state;             // previous state of key
43         int             counter;                // incremented each time key is down in handler
44         fix             timewentdown;   // simple counter incremented each time in interrupt and key is down
45         fix             timehelddown;   // counter to tell how long key is down -- gets reset to 0 by key routines
46         ubyte           downcount;              // number of key counts key was down
47         ubyte           upcount;                // number of times key was released
48 } Key_info;
49
50 typedef struct keyboard {
51         unsigned short          keybuffer[KEY_BUFFER_SIZE];
52         Key_info                keys[256];
53         fix                     time_pressed[KEY_BUFFER_SIZE];
54         unsigned int            keyhead, keytail;
55 } keyboard;
56
57 static keyboard key_data;
58
59 typedef struct key_props {
60         char *key_text;
61         unsigned char ascii_value;
62         unsigned char shifted_ascii_value;
63         SDLKey sym;
64 } key_props;
65
66 key_props key_properties[256] = {
67 { "",       255,    255,    -1                 },
68 { "ESC",    255,    255,    SDLK_ESCAPE        },
69 { "1",      '1',    '!',    SDLK_1             },
70 { "2",      '2',    '@',    SDLK_2             },
71 { "3",      '3',    '#',    SDLK_3             },
72 { "4",      '4',    '$',    SDLK_4             },
73 { "5",      '5',    '%',    SDLK_5             },
74 { "6",      '6',    '^',    SDLK_6             },
75 { "7",      '7',    '&',    SDLK_7             },
76 { "8",      '8',    '*',    SDLK_8             },
77 { "9",      '9',    '(',    SDLK_9             },
78 { "0",      '0',    ')',    SDLK_0             },
79 { "-",      '-',    '_',    SDLK_MINUS         },
80 { "=",      '=',    '+',    SDLK_EQUALS        },
81 { "BSPC",   255,    255,    SDLK_BACKSPACE     },
82 { "TAB",    255,    255,    SDLK_TAB           },
83 { "Q",      'q',    'Q',    SDLK_q             },
84 { "W",      'w',    'W',    SDLK_w             },
85 { "E",      'e',    'E',    SDLK_e             },
86 { "R",      'r',    'R',    SDLK_r             },
87 { "T",      't',    'T',    SDLK_t             },
88 { "Y",      'y',    'Y',    SDLK_y             },
89 { "U",      'u',    'U',    SDLK_u             },
90 { "I",      'i',    'I',    SDLK_i             },
91 { "O",      'o',    'O',    SDLK_o             },
92 { "P",      'p',    'P',    SDLK_p             },
93 { "[",      '[',    '{',    SDLK_LEFTBRACKET   },
94 { "]",      ']',    '}',    SDLK_RIGHTBRACKET  },
95 //edited 06/08/99 Matt Mueller - set to correct key_text
96 { "\x83",   255,    255,    SDLK_RETURN        },
97 //end edit -MM
98 { "LCTRL",  255,    255,    SDLK_LCTRL         },
99 { "A",      'a',    'A',    SDLK_a             },
100 { "S",      's',    'S',    SDLK_s             },
101 { "D",      'd',    'D',    SDLK_d             },
102 { "F",      'f',    'F',    SDLK_f             },
103 { "G",      'g',    'G',    SDLK_g             },
104 { "H",      'h',    'H',    SDLK_h             },
105 { "J",      'j',    'J',    SDLK_j             },
106 { "K",      'k',    'K',    SDLK_k             },
107 { "L",      'l',    'L',    SDLK_l             },
108 //edited 06/08/99 Matt Mueller - set to correct sym
109 { ";",      ';',    ':',    SDLK_SEMICOLON         },
110 //end edit -MM
111 { "'",      '\'',   '"',    SDLK_QUOTE         },
112 //edited 06/08/99 Matt Mueller - set to correct sym
113 { "`",      '`',    '~',    SDLK_BACKQUOTE     },
114 //end edit -MM
115 { "LSHFT",  255,    255,    SDLK_LSHIFT        },
116 { "\\",     '\\',   '|',    SDLK_BACKSLASH     },
117 { "Z",      'z',    'Z',    SDLK_z             },
118 { "X",      'x',    'X',    SDLK_x             },
119 { "C",      'c',    'C',    SDLK_c             },
120 { "V",      'v',    'V',    SDLK_v             },
121 { "B",      'b',    'B',    SDLK_b             },
122 { "N",      'n',    'N',    SDLK_n             },
123 { "M",      'm',    'M',    SDLK_m             },
124 //edited 06/08/99 Matt Mueller - set to correct syms
125 { ",",      ',',    '<',    SDLK_COMMA  },
126 { ".",      '.',    '>',    SDLK_PERIOD },
127 { "/",      '/',    '?',    SDLK_SLASH  },
128 //end edit -MM
129 { "RSHFT",  255,    255,    SDLK_RSHIFT },
130 { "PAD*",   '*',    255,    SDLK_KP_MULTIPLY   },
131 { "LALT",   255,    255,    SDLK_LALT          },
132 { "SPC",    ' ',    ' ',    SDLK_SPACE         },
133 { "CPSLK",  255,    255,    SDLK_CAPSLOCK      },
134 { "F1",     255,    255,    SDLK_F1            },
135 { "F2",     255,    255,    SDLK_F2            },
136 { "F3",     255,    255,    SDLK_F3            },
137 { "F4",     255,    255,    SDLK_F4            },
138 { "F5",     255,    255,    SDLK_F5            },
139 { "F6",     255,    255,    SDLK_F6            },
140 { "F7",     255,    255,    SDLK_F7            },
141 { "F8",     255,    255,    SDLK_F8            },
142 { "F9",     255,    255,    SDLK_F9            },
143 { "F10",    255,    255,    SDLK_F10           },
144 { "NMLCK",  255,    255,    SDLK_NUMLOCK       },
145 { "SCLK",   255,    255,    SDLK_SCROLLOCK     },
146 { "PAD7",   255,    255,    SDLK_KP7           },
147 { "PAD8",   255,    255,    SDLK_KP8           },
148 { "PAD9",   255,    255,    SDLK_KP9           },
149 { "PAD-",   255,    255,    SDLK_KP_MINUS      },
150 { "PAD4",   255,    255,    SDLK_KP4           },
151 { "PAD5",   255,    255,    SDLK_KP5           },
152 { "PAD6",   255,    255,    SDLK_KP6           },
153 { "PAD+",   255,    255,    SDLK_KP_PLUS       },
154 { "PAD1",   255,    255,    SDLK_KP1           },
155 { "PAD2",   255,    255,    SDLK_KP2           },
156 { "PAD3",   255,    255,    SDLK_KP3           },
157 { "PAD0",   255,    255,    SDLK_KP0           },
158 { "PAD.",   255,    255,    SDLK_KP_PERIOD     },
159 { "",       255,    255,    -1                 },
160 { "",       255,    255,    -1                 },
161 { "",       255,    255,    -1                 },
162 { "F11",    255,    255,    SDLK_F11           },
163 { "F12",    255,    255,    SDLK_F12           },
164 { "",       255,    255,    -1                 },       
165 { "",       255,    255,    -1                 },
166 { "",       255,    255,    -1                 },
167 { "",       255,    255,    -1                 },
168 { "",       255,    255,    -1                 },
169 { "",       255,    255,    -1                 },
170 { "",       255,    255,    -1                 },
171 { "",       255,    255,    -1                 },
172 //edited 06/08/99 Matt Mueller - add pause ability
173 { "PAUSE",       255,    255,    SDLK_PAUSE                 },
174 //end edit -MM
175 { "",       255,    255,    -1                 },
176 { "",       255,    255,    -1                 },
177 { "",       255,    255,    -1                 },
178 { "",       255,    255,    -1                 },
179 { "",       255,    255,    -1                 },
180 { "",       255,    255,    -1                 },
181 { "",       255,    255,    -1                 },
182 { "",       255,    255,    -1                 },
183 { "",       255,    255,    -1                 },
184 { "",       255,    255,    -1                 },
185 { "",       255,    255,    -1                 },
186 { "",       255,    255,    -1                 },
187 { "",       255,    255,    -1                 },
188 { "",       255,    255,    -1                 },
189 { "",       255,    255,    -1                 },
190 { "",       255,    255,    -1                 },
191 { "",       255,    255,    -1                 },
192 { "",       255,    255,    -1                 },
193 { "",       255,    255,    -1                 },
194 { "",       255,    255,    -1                 },
195 { "",       255,    255,    -1                 },
196 { "",       255,    255,    -1                 },
197 { "",       255,    255,    -1                 },
198 { "",       255,    255,    -1                 },
199 { "",       255,    255,    -1                 },
200 { "",       255,    255,    -1                 },
201 { "",       255,    255,    -1                 },
202 { "",       255,    255,    -1                 },
203 { "",       255,    255,    -1                 },
204 { "",       255,    255,    -1                 },
205 { "",       255,    255,    -1                 },
206 { "",       255,    255,    -1                 },
207 { "",       255,    255,    -1                 },
208 { "",       255,    255,    -1                 },
209 { "",       255,    255,    -1                 },
210 { "",       255,    255,    -1                 },
211 { "",       255,    255,    -1                 },
212 { "",       255,    255,    -1                 },
213 { "",       255,    255,    -1                 },
214 { "",       255,    255,    -1                 },
215 { "",       255,    255,    -1                 },
216 { "",       255,    255,    -1                 },
217 { "",       255,    255,    -1                 },
218 { "",       255,    255,    -1                 },
219 { "",       255,    255,    -1                 },
220 { "",       255,    255,    -1                 },
221 { "",       255,    255,    -1                 },
222 { "",       255,    255,    -1                 },
223 { "",       255,    255,    -1                 },
224 { "",       255,    255,    -1                 },
225 { "",       255,    255,    -1                 },
226 { "",       255,    255,    -1                 },
227 { "",       255,    255,    -1                 },
228 { "",       255,    255,    -1                 },
229 { "",       255,    255,    -1                 },
230 { "",       255,    255,    -1                 },
231 { "",       255,    255,    -1                 },
232 { "",       255,    255,    -1                 },
233 //edited 06/08/99 Matt Mueller - set to correct key_text
234 { "PAD\x83",255,    255,    SDLK_KP_ENTER      },
235 //end edit -MM
236 //edited 06/08/99 Matt Mueller - set to correct sym
237 { "RCTRL",  255,    255,    SDLK_RCTRL            },
238 //end edit -MM
239 { "LCMD",   255,    255,    SDLK_LMETA         },
240 { "RCMD",   255,    255,    SDLK_RMETA         },
241 { "",       255,    255,    -1                 },
242 { "",       255,    255,    -1                 },
243 { "",       255,    255,    -1                 },
244 { "",       255,    255,    -1                 },
245 { "",       255,    255,    -1                 },
246 { "",       255,    255,    -1                 },
247 { "",       255,    255,    -1                 },
248 { "",       255,    255,    -1                 },
249 { "",       255,    255,    -1                 },
250 { "",       255,    255,    -1                 },
251 { "",       255,    255,    -1                 },
252 { "",       255,    255,    -1                 },
253 { "",       255,    255,    -1                 },
254 { "",       255,    255,    -1                 },
255 { "",       255,    255,    -1                 },
256 { "",       255,    255,    -1                 },
257 { "",       255,    255,    -1                 },
258 { "",       255,    255,    -1                 },
259 { "",       255,    255,    -1                 },
260 { "",       255,    255,    -1                 },
261 { "",       255,    255,    -1                 },
262 { "PAD/",   255,    255,    SDLK_KP_DIVIDE     },
263 { "",       255,    255,    -1                 },
264 //edited 06/08/99 Matt Mueller - add printscreen ability
265 { "PRSCR",       255,    255,    SDLK_PRINT                 },
266 //end edit -MM
267 { "RALT",   255,    255,    SDLK_RALT          },
268 { "",       255,    255,    -1                 },
269 { "",       255,    255,    -1                 },
270 { "",       255,    255,    -1                 },
271 { "",       255,    255,    -1                 },
272 { "",       255,    255,    -1                 },
273 { "",       255,    255,    -1                 },
274 { "",       255,    255,    -1                 },
275 { "",       255,    255,    -1                 },
276 { "",       255,    255,    -1                 },
277 { "",       255,    255,    -1                 },
278 { "",       255,    255,    -1                 },
279 { "",       255,    255,    -1                 },
280 { "",       255,    255,    -1                 },
281 { "",       255,    255,    -1                 },
282 { "HOME",   255,    255,    SDLK_HOME          },
283 //edited 06/08/99 Matt Mueller - set to correct key_text
284 { "UP",         255,    255,    SDLK_UP            },
285 //end edit -MM
286 { "PGUP",   255,    255,    SDLK_PAGEUP        },
287 { "",       255,    255,    -1                 },
288 //edited 06/08/99 Matt Mueller - set to correct key_text
289 { "LEFT",       255,    255,    SDLK_LEFT          },
290 //end edit -MM
291 { "",       255,    255,    -1                 },
292 //edited 06/08/99 Matt Mueller - set to correct key_text
293 { "RIGHT",      255,    255,    SDLK_RIGHT         },
294 //end edit -MM
295 { "",       255,    255,    -1                 },
296 //edited 06/08/99 Matt Mueller - set to correct key_text
297 { "END",    255,    255,    SDLK_END           },
298 //end edit -MM
299 { "DOWN",       255,    255,    SDLK_DOWN          },
300 { "PGDN",       255,    255,    SDLK_PAGEDOWN      },
301 { "INS",        255,    255,    SDLK_INSERT        },
302 { "DEL",        255,    255,    SDLK_DELETE        },
303 { "",       255,    255,    -1                 },
304 { "",       255,    255,    -1                 },
305 { "",       255,    255,    -1                 },
306 { "",       255,    255,    -1                 },
307 { "",       255,    255,    -1                 },
308 { "",       255,    255,    -1                 },
309 { "",       255,    255,    -1                 },
310 { "",       255,    255,    -1                 },
311 { "",       255,    255,    -1                 },
312 { "",       255,    255,    -1                 },
313 { "",       255,    255,    -1                 },
314 { "",       255,    255,    -1                 },
315 { "",       255,    255,    -1                 },
316 { "",       255,    255,    -1                 },
317 { "",       255,    255,    -1                 },
318 { "",       255,    255,    -1                 },
319 { "",       255,    255,    -1                 },
320 { "",       255,    255,    -1                 },
321 { "",       255,    255,    -1                 },
322 { "",       255,    255,    -1                 },
323 { "",       255,    255,    -1                 },
324 { "",       255,    255,    -1                 },
325 { "",       255,    255,    -1                 },
326 { "",       255,    255,    -1                 },
327 { "",       255,    255,    -1                 },
328 { "",       255,    255,    -1                 },
329 { "",       255,    255,    -1                 },
330 { "",       255,    255,    -1                 },
331 { "",       255,    255,    -1                 },
332 { "",       255,    255,    -1                 },
333 { "",       255,    255,    -1                 },
334 { "",       255,    255,    -1                 },
335 { "",       255,    255,    -1                 },
336 { "",       255,    255,    -1                 },
337 { "",       255,    255,    -1                 },
338 { "",       255,    255,    -1                 },
339 { "",       255,    255,    -1                 },
340 { "",       255,    255,    -1                 },
341 { "",       255,    255,    -1                 },
342 { "",       255,    255,    -1                 },
343 { "",       255,    255,    -1                 },
344 { "",       255,    255,    -1                 },
345 { "",       255,    255,    -1                 },
346 { "",       255,    255,    -1                 },
347 };
348
349 char *key_text[256];
350
351 void key_buid_key_text(void)
352 {
353 }
354
355 unsigned char key_to_ascii(int keycode )
356 {
357         int shifted;
358
359         shifted = keycode & KEY_SHIFTED;
360         keycode &= 0xFF;
361
362         if (shifted)
363                 return key_properties[keycode].shifted_ascii_value;
364         else
365                 return key_properties[keycode].ascii_value;
366 }
367
368
369 /* The list of keybindings */
370 static char *key_binding_list[256];
371
372
373 /* get the action bound to a key, if any */
374 char *key_binding(ubyte keycode)
375 {
376         return key_binding_list[keycode];
377 }
378
379
380 /* Write key bindings to file */
381 void key_write_bindings(CFILE *file)
382 {
383         int i;
384
385         for (i = 0; i < 256; i++)
386                 if (key_binding_list[i])
387                         PHYSFSX_printf(file, "bind %s \"%s\"\n", key_text[i], key_binding_list[i]);
388 }
389
390
391 /* bind */
392 /* FIXME: key_text is not really adequate for this */
393 void key_cmd_bind(int argc, char **argv)
394 {
395         char buf[CMD_MAX_LENGTH] = "";
396         int key = -1;
397         int i;
398
399         if (argc < 2)
400         {
401                 con_printf(CON_NORMAL, "key bindings:\n");
402                 for (i = 0; i < 256; i++) {
403                         if (!key_binding_list[i])
404                                 continue;
405                         con_printf(CON_NORMAL, "%s: %s\n", key_text[i], key_binding_list[i]);
406                 }
407                 return;
408         }
409
410         for (i = 0; i < 256; i++) {
411                 if (!stricmp(argv[1], key_text[i])) {
412                         key = i;
413                         break;
414                 }
415         }
416
417         if (key < 0) {
418                 con_printf(CON_CRITICAL, "bind: key %s not found\n", argv[1]);
419                 return;
420         }
421
422         if (argc < 3) {
423                 if (key_binding_list[key])
424                         con_printf(CON_NORMAL, "%s: %s\n", key_text[key], key_binding_list[key]);
425                 else
426                         con_printf(CON_NORMAL, "%s is unbound\n", key_text[key]);
427                 return;
428         }
429
430         for (i = 2; i < argc; i++) {
431                 if (i > 2)
432                         strncat(buf, " ", CMD_MAX_LENGTH);
433                 strncat(buf, argv[i], CMD_MAX_LENGTH);
434         }
435
436         if (key_binding_list[key])
437                 d_free(key_binding_list[key]);
438         key_binding_list[key] = d_strdup(buf);
439 }
440
441
442 /* unbind */
443 void key_cmd_unbind(int argc, char **argv)
444 {
445         unsigned int key;
446
447         if (argc < 2)
448                 return;
449
450         for (key = 0; key < 256; key++) {
451                 if (!stricmp(argv[1], key_text[key])) {
452                         break;
453                 }
454         }
455
456         if (key_binding_list[key])
457                 d_free(key_binding_list[key]);
458         key_binding_list[key] = NULL;
459 }
460
461
462 static void key_handle_binding(int keycode, int state)
463 {
464         if (!key_binding_list[keycode])
465                 return;
466
467         if (Game_paused)
468                 return;
469
470         if (Function_mode != FMODE_GAME)
471                 return;
472
473         if (CON_isVisible())
474                 return;
475
476         if (!state && key_binding_list[keycode][0] == '+')
477                 cmd_appendf("-%s", &key_binding_list[keycode][1]);
478         else if (state)
479                 cmd_append(key_binding_list[keycode]);
480 }
481
482
483 void key_handler(SDL_KeyboardEvent *event)
484 {
485         ubyte state;
486         int i, keycode, event_key, key_state;
487         Key_info *key;
488         unsigned char temp;
489
490         event_key = event->keysym.sym;
491
492         key_state = (event->state == SDL_PRESSED); //  !(wInfo & KF_UP);
493         //=====================================================
494         //Here a translation from win keycodes to mac keycodes!
495         //=====================================================
496
497         for (i = 255; i >= 0; i--) {
498
499                 keycode = i;
500                 key = &(key_data.keys[keycode]);
501                 if (key_properties[i].sym == event_key) {
502                         state = key_state;
503                         key_handle_binding(keycode, state);
504                 } else
505                         state = key->last_state;
506                         
507                 if ( key->last_state == state ) {
508                         if (state) {
509                                 key->counter++;
510                                 keyd_last_pressed = keycode;
511                                 keyd_time_when_last_pressed = timer_get_fixed_seconds();
512                         }
513                 } else {
514                         if (state)      {
515                                 keyd_last_pressed = keycode;
516                                 keyd_pressed[keycode] = 1;
517                                 key->downcount += state;
518                                 key->state = 1;
519                                 key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds();
520                                 key->counter++;
521                         } else {        
522                                 keyd_pressed[keycode] = 0;
523                                 keyd_last_released = keycode;
524                                 key->upcount += key->state;
525                                 key->state = 0;
526                                 key->counter = 0;
527                                 key->timehelddown += timer_get_fixed_seconds() - key->timewentdown;
528                         }
529                 }
530                 if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) {
531                         if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT])
532                                 keycode |= KEY_SHIFTED;
533                         if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT])
534                                 keycode |= KEY_ALTED;
535                         if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL])
536                                 keycode |= KEY_CTRLED;
537                         if ( keyd_pressed[KEY_DELETE] )
538                                 keycode |= KEY_DEBUGGED;
539                         if ( keyd_pressed[KEY_LMETA] || keyd_pressed[KEY_RMETA])
540                                 keycode |= KEY_METAED;
541
542                         temp = key_data.keytail+1;
543                         if ( temp >= KEY_BUFFER_SIZE ) temp=0;
544                         if (temp!=key_data.keyhead)     {
545                                 key_data.keybuffer[key_data.keytail] = keycode;
546                                 key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
547                                 key_data.keytail = temp;
548                         }
549                 }
550                 key->last_state = state;
551         }
552 }
553
554 void key_close()
555 {
556         int i;
557
558         for (i = 0; i < 256; i++)
559                 if (key_binding_list[i])
560                         d_free(key_binding_list[i]);
561
562  Installed = 0;
563 }
564
565 void key_init()
566 {
567   int i;
568   
569   if (Installed) return;
570
571   Installed=1;
572
573   keyd_time_when_last_pressed = timer_get_fixed_seconds();
574   keyd_buffer_type = 1;
575   keyd_repeat = 1;
576   
577   for(i=0; i<256; i++)
578      key_text[i] = key_properties[i].key_text;
579
580         cmd_addcommand("bind", key_cmd_bind);
581         cmd_addcommand("unbind", key_cmd_unbind);
582
583   // Clear the keyboard array
584   key_flush();
585   atexit(key_close);
586 }
587
588 void key_flush()
589 {
590         int i;
591         fix curtime;
592
593         if (!Installed)
594                 key_init();
595
596         key_data.keyhead = key_data.keytail = 0;
597
598         //Clear the keyboard buffer
599         for (i=0; i<KEY_BUFFER_SIZE; i++ )      {
600                 key_data.keybuffer[i] = 0;
601                 key_data.time_pressed[i] = 0;
602         }
603
604 //use gettimeofday here:
605         curtime = timer_get_fixed_seconds();
606
607         for (i=0; i<256; i++ )  {
608                 keyd_pressed[i] = 0;
609                 key_data.keys[i].state = 1;
610                 key_data.keys[i].last_state = 0;
611                 key_data.keys[i].timewentdown = curtime;
612                 key_data.keys[i].downcount=0;
613                 key_data.keys[i].upcount=0;
614                 key_data.keys[i].timehelddown = 0;
615                 key_data.keys[i].counter = 0;
616         }
617 }
618
619 int add_one(int n)
620 {
621  n++;
622  if ( n >= KEY_BUFFER_SIZE ) n=0;
623  return n;
624 }
625
626 int key_checkch()
627 {
628         int is_one_waiting = 0;
629         event_poll();
630         if (key_data.keytail!=key_data.keyhead)
631                 is_one_waiting = 1;
632         return is_one_waiting;
633 }
634
635 int key_inkey()
636 {
637         int key = 0;
638         if (!Installed)
639                 key_init();
640         event_poll();
641         if (key_data.keytail!=key_data.keyhead) {
642                 key = key_data.keybuffer[key_data.keyhead];
643                 key_data.keyhead = add_one(key_data.keyhead);
644         }
645 //added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such
646         else timer_delay(1);
647 //end addition - Matt Mueller
648              
649         return key;
650 }
651
652 int key_inkey_time(fix * time)
653 {
654         int key = 0;
655
656         if (!Installed)
657                 key_init();
658         event_poll();
659         if (key_data.keytail!=key_data.keyhead) {
660                 key = key_data.keybuffer[key_data.keyhead];
661                 *time = key_data.time_pressed[key_data.keyhead];
662                 key_data.keyhead = add_one(key_data.keyhead);
663         }
664         return key;
665 }
666
667 int key_peekkey()
668 {
669         int key = 0;
670         event_poll();
671         if (key_data.keytail!=key_data.keyhead)
672                 key = key_data.keybuffer[key_data.keyhead];
673
674         return key;
675 }
676
677 int key_getch()
678 {
679         int dummy=0;
680
681         if (!Installed)
682                 return 0;
683 //              return getch();
684
685         while (!key_checkch())
686                 dummy++;
687         return key_inkey();
688 }
689
690 unsigned int key_get_shift_status()
691 {
692         unsigned int shift_status = 0;
693
694         if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] )
695                 shift_status |= KEY_SHIFTED;
696
697         if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
698                 shift_status |= KEY_ALTED;
699
700         if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] )
701                 shift_status |= KEY_CTRLED;
702
703         if ( keyd_pressed[KEY_LMETA] || keyd_pressed[KEY_RMETA] )
704                 shift_status |= KEY_METAED;
705
706 #ifndef NDEBUG
707         if (keyd_pressed[KEY_DELETE])
708                 shift_status |=KEY_DEBUGGED;
709 #endif
710
711         return shift_status;
712 }
713
714 // Returns the number of seconds this key has been down since last call.
715 fix key_down_time(int scancode)
716 {
717         fix time_down, time;
718
719         event_poll();
720         if ((scancode<0)|| (scancode>255)) return 0;
721
722         if (!keyd_pressed[scancode]) {
723                 time_down = key_data.keys[scancode].timehelddown;
724                 key_data.keys[scancode].timehelddown = 0;
725         } else {
726                 time = timer_get_fixed_seconds();
727                 time_down = time - key_data.keys[scancode].timewentdown;
728                 key_data.keys[scancode].timewentdown = time;
729         }
730
731         return time_down;
732 }
733
734 unsigned int key_down_count(int scancode)
735 {
736         int n;
737         event_poll();
738         if ((scancode<0)|| (scancode>255)) return 0;
739
740         n = key_data.keys[scancode].downcount;
741         key_data.keys[scancode].downcount = 0;
742
743         return n;
744 }
745
746 unsigned int key_up_count(int scancode)
747 {
748         int n;
749         event_poll();
750         if ((scancode<0)|| (scancode>255)) return 0;
751
752         n = key_data.keys[scancode].upcount;
753         key_data.keys[scancode].upcount = 0;
754
755         return n;
756 }