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