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