]> icculus.org git repositories - btb/d2x.git/blob - arch/linux/svgalib/key.c
This commit was generated by cvs2svn to compensate for changes in r5,
[btb/d2x.git] / arch / linux / svgalib / key.c
1 /// SDL keyboard input support
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <vgakeyboard.h> 
7
8 #include "event.h"
9 #include "error.h"
10 #include "key.h"
11 #include "timer.h"
12
13 //added on 9/3/98 by Matt Mueller to free some cpu instead of hogging during menus and such
14 #include "d_delay.h"
15 //end this section addition - Matt Mueller
16
17 #define KEY_BUFFER_SIZE 16
18
19 static unsigned char Installed = 0;
20
21 //-------- Variable accessed by outside functions ---------
22 unsigned char           keyd_buffer_type;               // 0=No buffer, 1=buffer ASCII, 2=buffer scans
23 unsigned char           keyd_repeat;
24 unsigned char           keyd_editor_mode;
25 volatile unsigned char  keyd_last_pressed;
26 volatile unsigned char  keyd_last_released;
27 volatile unsigned char  keyd_pressed[256];
28 volatile int            keyd_time_when_last_pressed;
29
30 typedef struct Key_info {
31         ubyte           state;                  // state of key 1 == down, 0 == up
32         ubyte           last_state;             // previous state of key
33         int             counter;                // incremented each time key is down in handler
34         fix             timewentdown;   // simple counter incremented each time in interrupt and key is down
35         fix             timehelddown;   // counter to tell how long key is down -- gets reset to 0 by key routines
36         ubyte           downcount;              // number of key counts key was down
37         ubyte           upcount;                // number of times key was released
38 } Key_info;
39
40 typedef struct keyboard {
41         unsigned short          keybuffer[KEY_BUFFER_SIZE];
42         Key_info                keys[256];
43         fix                     time_pressed[KEY_BUFFER_SIZE];
44         unsigned int            keyhead, keytail;
45 } keyboard;
46
47 static /*volatile*/ keyboard key_data;
48
49 char * key_text[256] = {
50 "","ESC","1","2","3","4","5","6","7","8","9","0","-",
51 "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",
52 "P","[","]","\83","LCTRL","A","S","D","F",
53 "G","H","J","K","L",";","'","`",
54 "LSHFT","\\","Z","X","C","V","B","N","M",",",
55 ".","/","RSHFT","PAD*","LALT","SPC",
56 "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",
57 "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",
58 "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0",
59 "PAD.","","","","F11","F12","","","","","","","","","",
60 "","","","","","","","","","","","","","","","","","","","",
61 "","","","","","","","","","","","","","","","","","","","",
62 "","","","","","","","","","","","","","","","","","",
63 "PAD\83","RCTRL","","","","","","","","","","","","","",
64 "","","","","","","","","","","PAD/","","","RALT","",
65 "","","","","","","","","","","","","","HOME","\82","PGUP",
66 "","\81","","\7f","","END","\80","PGDN","INS",
67 "DEL","","","","","","","","","","","","","","","","","",
68 "","","","","","","","","","","","","","","","","","","","",
69 "","","","","","","" };
70
71 unsigned char ascii_table[128] = 
72 { 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255,
73   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255,
74   'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`',
75   255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*',
76   255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
77   255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
78   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
79   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
80   255,255,255,255,255,255,255,255 };
81
82 unsigned char shifted_ascii_table[128] = 
83 { 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255,
84   'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255,
85   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 
86   255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255,
87   255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
88   255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
89   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
90   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
91   255,255,255,255,255,255,255,255 };
92
93 //killed on 10/03/98 by Matt Mueller
94 //unsigned char key_to_ascii(int a)
95 //{
96 // if (!isprint(a)) return 255;
97 // if (a & KEY_SHIFTED) {
98 //  return (toupper((unsigned char) a));
99 // } else {
100 //  return ((unsigned char) a);
101 // }
102 //}
103 //end kill -MM
104
105 //added on 10/03/98 by Matt Mueller to fix shifted keys (copied from dos/key.c)
106 unsigned char key_to_ascii(int keycode)
107 {
108         int shifted;
109
110         shifted = keycode & KEY_SHIFTED;
111         keycode &= 0xFF;
112
113         if ( keycode>=127 )
114                 return 255;
115
116         if (shifted)
117                 return shifted_ascii_table[keycode];
118         else
119                 return ascii_table[keycode];
120 }
121 //end addition -MM
122
123 void key_handler(int scancode, int press)
124 {
125         ubyte state, key_state;
126         int i, keycode, event_key;
127         Key_info *key;
128         unsigned char temp;
129
130         if (press == KEY_EVENTPRESS)
131                 key_state = 1;
132         else if (press == KEY_EVENTRELEASE)
133                 key_state = 0;
134         else
135                 return;
136
137         event_key = scancode;
138
139         //=====================================================
140         //Here a translation from win keycodes to mac keycodes!
141         //=====================================================
142
143         for (i = 255; i >= 0; i--) {
144
145                 keycode = i;
146                 key = &(key_data.keys[keycode]);
147                 if (i == event_key)
148                         state = key_state;
149                 else
150                         state = key->last_state;
151                         
152                 if ( key->last_state == state ) {
153                         if (state) {
154                                 key->counter++;
155                                 keyd_last_pressed = keycode;
156                                 keyd_time_when_last_pressed = timer_get_fixed_seconds();
157                         }
158                 } else {
159                         if (state)      {
160                                 keyd_last_pressed = keycode;
161                                 keyd_pressed[keycode] = 1;
162                                 key->downcount += state;
163                                 key->state = 1;
164                                 key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds();
165                                 key->counter++;
166                         } else {        
167                                 keyd_pressed[keycode] = 0;
168                                 keyd_last_released = keycode;
169                                 key->upcount += key->state;
170                                 key->state = 0;
171                                 key->counter = 0;
172                                 key->timehelddown += timer_get_fixed_seconds() - key->timewentdown;
173                         }
174                 }
175                 if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) {
176                         if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT])
177                                 keycode |= KEY_SHIFTED;
178                         if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT])
179                                 keycode |= KEY_ALTED;
180                         if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL])
181                                 keycode |= KEY_CTRLED;
182                         if ( keyd_pressed[KEY_DELETE] )
183                                 keycode |= KEY_DEBUGGED;
184                         temp = key_data.keytail+1;
185                         if ( temp >= KEY_BUFFER_SIZE ) temp=0;
186                         if (temp!=key_data.keyhead)     {
187                                 key_data.keybuffer[key_data.keytail] = keycode;
188                                 key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
189                                 key_data.keytail = temp;
190                         }
191                 }
192                 key->last_state = state;
193         }
194 }
195
196 void key_close()
197 {
198         Installed = 0;
199         keyboard_close();
200 }
201
202 void key_init()
203 {
204         if (keyboard_init())
205                 Error ("SVGAlib Keyboard Init Failed");
206         Installed=1;
207
208         keyboard_seteventhandler (key_handler);
209         keyd_time_when_last_pressed = timer_get_fixed_seconds();
210         keyd_buffer_type = 1;
211         keyd_repeat = 1;
212
213 // Clear the keyboard array
214         key_flush();
215         atexit(key_close);
216 }
217
218 void key_flush()
219 {
220         int i;
221         fix curtime;
222
223         if (!Installed)
224                 key_init();
225
226         key_data.keyhead = key_data.keytail = 0;
227
228         //Clear the keyboard buffer
229         for (i=0; i<KEY_BUFFER_SIZE; i++ )      {
230                 key_data.keybuffer[i] = 0;
231                 key_data.time_pressed[i] = 0;
232         }
233
234 //use gettimeofday here:
235         curtime = timer_get_fixed_seconds();
236
237         for (i=0; i<256; i++ )  {
238                 keyd_pressed[i] = 0;
239                 key_data.keys[i].state = 1;
240                 key_data.keys[i].last_state = 0;
241                 key_data.keys[i].timewentdown = curtime;
242                 key_data.keys[i].downcount=0;
243                 key_data.keys[i].upcount=0;
244                 key_data.keys[i].timehelddown = 0;
245                 key_data.keys[i].counter = 0;
246         }
247 }
248
249 int add_one(int n)
250 {
251  n++;
252  if ( n >= KEY_BUFFER_SIZE ) n=0;
253  return n;
254 }
255
256 int key_checkch()
257 {
258         int is_one_waiting = 0;
259         event_poll();
260         if (key_data.keytail!=key_data.keyhead)
261                 is_one_waiting = 1;
262         return is_one_waiting;
263 }
264
265 int key_inkey()
266 {
267         int key = 0;
268         if (!Installed)
269                 key_init();
270         event_poll();
271         if (key_data.keytail!=key_data.keyhead) {
272                 key = key_data.keybuffer[key_data.keyhead];
273                 key_data.keyhead = add_one(key_data.keyhead);
274         }
275 //added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such
276 //      else d_delay(1);
277 //end addition - Matt Mueller
278         return key;
279 }
280
281 int key_inkey_time(fix * time)
282 {
283         int key = 0;
284
285         if (!Installed)
286                 key_init();
287         event_poll();
288         if (key_data.keytail!=key_data.keyhead) {
289                 key = key_data.keybuffer[key_data.keyhead];
290                 *time = key_data.time_pressed[key_data.keyhead];
291                 key_data.keyhead = add_one(key_data.keyhead);
292         }
293         return key;
294 }
295
296 int key_peekkey()
297 {
298         int key = 0;
299         event_poll();
300         if (key_data.keytail!=key_data.keyhead)
301                 key = key_data.keybuffer[key_data.keyhead];
302
303         return key;
304 }
305
306 int key_getch()
307 {
308         int dummy=0;
309
310         if (!Installed)
311                 return 0;
312 //              return getch();
313
314         while (!key_checkch())
315                 dummy++;
316         return key_inkey();
317 }
318
319 unsigned int key_get_shift_status()
320 {
321         unsigned int shift_status = 0;
322
323         if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] )
324                 shift_status |= KEY_SHIFTED;
325
326         if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
327                 shift_status |= KEY_ALTED;
328
329         if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] )
330                 shift_status |= KEY_CTRLED;
331
332 #ifndef NDEBUG
333         if (keyd_pressed[KEY_DELETE])
334                 shift_status |=KEY_DEBUGGED;
335 #endif
336
337         return shift_status;
338 }
339
340 // Returns the number of seconds this key has been down since last call.
341 fix key_down_time(int scancode)
342 {
343         fix time_down, time;
344
345         event_poll();
346         if ((scancode<0)|| (scancode>255)) return 0;
347
348         if (!keyd_pressed[scancode]) {
349                 time_down = key_data.keys[scancode].timehelddown;
350                 key_data.keys[scancode].timehelddown = 0;
351         } else {
352                 time = timer_get_fixed_seconds();
353                 time_down = time - key_data.keys[scancode].timewentdown;
354                 key_data.keys[scancode].timewentdown = time;
355         }
356
357         return time_down;
358 }
359
360 unsigned int key_down_count(int scancode)
361 {
362         int n;
363         event_poll();
364         if ((scancode<0)|| (scancode>255)) return 0;
365
366         n = key_data.keys[scancode].downcount;
367         key_data.keys[scancode].downcount = 0;
368
369         return n;
370 }
371
372 unsigned int key_up_count(int scancode)
373 {
374         int n;
375         event_poll();
376         if ((scancode<0)|| (scancode>255)) return 0;
377
378         n = key_data.keys[scancode].upcount;
379         key_data.keys[scancode].upcount = 0;
380
381         return n;
382 }
383