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