]> icculus.org git repositories - btb/d2x.git/blob - unused/win95/key.c
remove rcs tags
[btb/d2x.git] / unused / win95 / key.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14
15 #define _WIN32
16 #define WIN32_LEAN_AND_MEAN
17
18 #include <windows.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <conio.h>
22
23 //#define WATCOM_10
24
25 #include "mono.h"
26 #include "error.h"
27 #include "key.h"
28 #include "timer.h"
29
30 #define KEY_BUFFER_SIZE 16
31
32 //-------- Variable accessed by outside functions ---------
33 unsigned char                           keyd_print_screen=0;
34
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 keyboard {
44         unsigned short          keybuffer[KEY_BUFFER_SIZE];
45         fix                                     time_pressed[KEY_BUFFER_SIZE];
46         fix                                     TimeKeyWentDown[256];
47         fix                                     TimeKeyHeldDown[256];
48         unsigned int            NumDowns[256];
49         unsigned int            NumUps[256];
50         unsigned int            keyhead, keytail;
51         unsigned char           E0Flag;
52         unsigned char           E1Flag;
53 } keyboard;
54
55 static volatile keyboard key_data;
56
57 static unsigned char Installed=0;
58
59 unsigned char ascii_table[128] = 
60 { 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255,
61   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255,
62   'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`',
63   255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 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,255,
66   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
67   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
68   255,255,255,255,255,255,255,255 };
69
70 unsigned char shifted_ascii_table[128] = 
71 { 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255,
72   'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255,
73   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 
74   255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 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,255,
77   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,255,
79   255,255,255,255,255,255,255,255 };
80
81
82 //      Initialization and Cleanup Routines
83
84 void key_init()
85 {
86         keyd_time_when_last_pressed = timer_get_fixed_seconds();
87         keyd_buffer_type = 1;
88         keyd_repeat = 1;
89         key_data.E0Flag = 0;
90         key_data.E1Flag = 0;
91
92         // Clear the keyboard array
93         key_flush();
94         if (!Installed) Installed = 1;
95 }
96
97
98 void key_close()
99 {
100         if (!Installed) return;
101         key_clear_bios_buffer_all();
102 }
103
104
105 extern char key_to_ascii(int keycode )
106 {
107         int shifted;
108
109         shifted = keycode & KEY_SHIFTED;
110         keycode &= 0xFF;
111
112         if ( keycode>=127 )
113                 return 255;
114
115         if (shifted)
116                 return shifted_ascii_table[keycode];
117         else
118                 return ascii_table[keycode];
119 }
120
121 void key_clear_bios_buffer_all()
122 {
123
124 }
125
126 void key_clear_bios_buffer()
127 {
128
129 }
130
131 void key_flush()
132 {
133         int i;
134         fix CurTime;
135
136         // Clear the BIOS buffer
137         key_clear_bios_buffer();
138
139         key_data.keyhead = key_data.keytail = 0;
140
141         //Clear the keyboard buffer
142         for (i=0; i<KEY_BUFFER_SIZE; i++ )      {
143                 key_data.keybuffer[i] = 0;
144                 key_data.time_pressed[i] = 0;
145         }
146         
147         //Clear the keyboard array
148
149         CurTime =timer_get_fixed_secondsX();
150
151         for (i=0; i<256; i++ )  {
152                 keyd_pressed[i] = 0;
153                 key_data.TimeKeyWentDown[i] = CurTime;
154                 key_data.TimeKeyHeldDown[i] = 0;
155                 key_data.NumDowns[i]=0;
156                 key_data.NumUps[i]=0;
157         }
158         keyd_print_screen = 0;
159 }
160
161 int add_one( int n )
162 {
163         n++;
164         if ( n >= KEY_BUFFER_SIZE ) n=0;
165         return n;
166 }
167
168 // Returns 1 if character waiting... 0 otherwise
169 int key_checkch()
170 {
171         int is_one_waiting = 0;
172
173         key_clear_bios_buffer();
174
175         if (key_data.keytail!=key_data.keyhead)
176                 is_one_waiting = 1;
177
178         return is_one_waiting;
179 }
180
181 int key_inkey()
182 {
183         int key = 0;
184
185         key_clear_bios_buffer();
186
187         if (key_data.keytail!=key_data.keyhead) {
188                 key = key_data.keybuffer[key_data.keyhead];
189                 key_data.keyhead = add_one(key_data.keyhead);
190         }
191
192         return key;
193 }
194
195 int key_inkey_time(fix * time)
196 {
197         int key = 0;
198
199         key_clear_bios_buffer();
200
201         if (key_data.keytail!=key_data.keyhead) {
202                 key = key_data.keybuffer[key_data.keyhead];
203                 *time = key_data.time_pressed[key_data.keyhead];
204                 key_data.keyhead = add_one(key_data.keyhead);
205         }
206
207         return key;
208 }
209
210
211 void key_putkey (unsigned short keycode)
212  {
213   // this function simulates a key stroke entered
214   char temp;
215   
216
217   temp = key_data.keytail+1;
218   if ( temp >= KEY_BUFFER_SIZE ) temp=0;
219   if (temp!=key_data.keyhead)   
220     {
221                 key_data.keybuffer[key_data.keytail] = keycode;
222                 key_data.keytail = temp;
223     }
224  }  
225
226
227 int key_peekkey()
228 {
229         int key = 0;
230
231         key_clear_bios_buffer();
232
233         if (key_data.keytail!=key_data.keyhead) {
234                 key = key_data.keybuffer[key_data.keyhead];
235         }
236
237         return key;
238 }
239
240 // If not installed, uses BIOS and returns getch();
241 //      Else returns pending key (or waits for one if none waiting).
242 int key_getch()
243 {
244         int dummy=0;
245         
246         if (!Installed)
247                 return getch();
248
249         while (!key_checkch())
250                 dummy++;
251         return key_inkey();
252 }
253
254 unsigned int key_get_shift_status()
255 {
256         unsigned int shift_status = 0;
257
258
259         key_clear_bios_buffer();
260
261         if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] )
262                 shift_status |= KEY_SHIFTED;
263
264         if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
265                 shift_status |= KEY_ALTED;
266
267         if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] )
268                 shift_status |= KEY_CTRLED;
269
270 #ifndef NDEBUG
271         if (keyd_pressed[KEY_DELETE])
272                 shift_status |=KEY_DEBUGGED;
273 #endif
274
275
276         return shift_status;
277 }
278
279 // Returns the number of seconds this key has been down since last call.
280 fix key_down_time(int scancode) {
281         fix time_down, time;
282
283         if ((scancode<0)|| (scancode>255)) return 0;
284
285 #ifndef NDEBUG
286         if (keyd_editor_mode && key_get_shift_status() )
287                 return 0;  
288 #endif
289
290         if ( !keyd_pressed[scancode] )  {
291                 time_down = key_data.TimeKeyHeldDown[scancode];
292                 key_data.TimeKeyHeldDown[scancode] = 0;
293         } else  {
294                 time = timer_get_fixed_secondsX();
295                 time_down =  time - key_data.TimeKeyWentDown[scancode];
296                 key_data.TimeKeyWentDown[scancode] = time;
297         }
298
299         return time_down;
300 }
301
302 // Returns number of times key has went from up to down since last call.
303 unsigned int key_down_count(int scancode)       {
304         int n;
305
306         if ((scancode<0)|| (scancode>255)) return 0;
307
308         n = key_data.NumDowns[scancode];
309         key_data.NumDowns[scancode] = 0;
310
311         return n;
312 }
313
314
315 // Returns number of times key has went from down to up since last call.
316 unsigned int key_up_count(int scancode) {
317         int n;
318
319         if ((scancode<0)|| (scancode>255)) return 0;
320
321         n = key_data.NumUps[scancode];
322         key_data.NumUps[scancode] = 0;
323
324         return n;
325 }
326
327 // Use intrinsic forms so that we stay in the locked interrup code.
328
329 void Int5();
330 #pragma aux Int5 = "int 5";
331
332
333
334 // Send keyboard message to Descent keyboard system.
335
336 void send_key_msg(UINT msg, WPARAM vkeycode, LPARAM keypack)
337 {
338         unsigned char scancode, temp;
339         unsigned short keycode;   
340         
341 //      Extract 8-bit OEM scancode
342         scancode = (char)((keypack >> 16) & 0xff);
343
344         if (vkeycode == VK_SNAPSHOT) {
345                 scancode = KEY_PRINT_SCREEN;            
346                 keyd_print_screen = 1;
347         }
348         else if (keypack & 0x01000000) scancode |= 0x80;
349         if (vkeycode == VK_PAUSE) scancode = KEY_PAUSE;
350
351         switch (msg)
352         {
353                 case WM_SYSKEYDOWN:
354                 case WM_KEYDOWN:                                        // Keyboard down
355                 // Handle Pauses the easy way.
356                         keyd_last_pressed = scancode;
357                         keyd_time_when_last_pressed = timer_get_fixed_secondsX();
358                         
359                         if (!keyd_pressed[scancode]) {
360                         // First time key is down.
361                                 key_data.TimeKeyWentDown[scancode] = timer_get_fixed_secondsX();
362                                 keyd_pressed[scancode] = 1;
363                                 key_data.NumDowns[scancode]++;
364
365                         #ifndef NDEBUG
366                                 if ((keyd_pressed[KEY_LSHIFT]) && (scancode == KEY_BACKSP)) {
367                                         keyd_pressed[KEY_LSHIFT] = 0;
368                                 //      Int5();
369                                 }
370                         #endif
371                         }
372                         else if (!keyd_repeat) {
373                         // don't buffer repeating key if repeat mode is off     
374                                 scancode = 0xaa;
375                         }
376                         if (scancode != 0xaa) {
377                                 keycode = (unsigned short)scancode;
378                                 
379                                 if (keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) 
380                                         keycode |= KEY_SHIFTED;
381
382                                 if (keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]) 
383                                         keycode |= KEY_ALTED;                   
384
385                                 if (keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL])
386                                         keycode |= KEY_CTRLED;
387                         
388                         #ifndef NDEBUG
389                                 if (keyd_pressed[KEY_DELETE])
390                                         keycode |= KEY_DEBUGGED;
391                         #endif
392
393                                 temp = key_data.keytail+1;
394                                 if (temp >= KEY_BUFFER_SIZE) temp = 0;
395
396                                 if (temp!= key_data.keyhead) {
397                                         key_data.keybuffer[key_data.keytail] = keycode;
398                                         key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
399                                         key_data.keytail = temp;
400                                 }
401                         }
402                         break;
403                         
404                 case WM_SYSKEYUP:
405                 case WM_KEYUP:                                          // handle key ups
406                         keyd_last_released = scancode;
407                         keyd_pressed[scancode] = 0;
408                         key_data.NumUps[scancode]++;
409                         temp = 0;
410                         temp |= keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT];
411                         temp |= keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT];
412                         temp |= keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL];
413                 
414                 #ifndef NDEBUG
415                         temp |= keyd_pressed[KEY_DELETE];
416                         if (!(keyd_editor_mode && temp))
417                 #endif 
418                                 // NOTICE LINK TO ABOVE IF!!!!
419                                 key_data.TimeKeyHeldDown[scancode] += timer_get_fixed_secondsX() - 
420                                                                                                                         key_data.TimeKeyWentDown[scancode];
421                         break;
422         }       // switch (msg)
423
424 }