Major cleanup and bug fixes.
[crow/jumpnbump.git] / sdl / interrpt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #ifndef _MSC_VER
5 #include <unistd.h>
6 #endif
7 #include "globals.h"
8
9
10 struct {
11         char enabled;
12 } keyb_handler_info;
13
14 volatile char keyb[256];
15 char last_keys[50];
16
17 unsigned char scancode2ascii[256] = {
18         0, 0, 49, 50, 51, 52, 53, 54, 55, 56,           /* 0-9 */
19         57, 48, 45, 0, 0, 0, 113, 119, 101, 114,        /* 10-19 */
20         116, 121, 117, 105, 111, 112, 0, 0, 0, 0,       /* 20-29 */
21         97, 115, 100, 102, 103, 104, 106, 107, 108, 0,  /* 30-39 */
22         0, 0, 0, 0, 122, 120, 99, 118, 98, 110,         /* 40-49 */
23         109, 44, 46, 47, 0, 0, 0, 32, 0, 0,             /* 50-59 */
24         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43         0, 0, 0, 0, 0, 0
44 };
45
46 #ifndef USE_SDL
47 _go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo;
48 #endif
49
50 void keyb_handler()
51 {
52         unsigned char key;
53         static char extended;
54         int c1;
55
56         key = 0;
57 #ifndef USE_SDL
58         key = inportb(0x60);
59 #endif
60
61         if (key == 0xe0)
62                 extended = 1;
63         else {
64                 if (extended == 0) {
65                         if ((key & 0x80) == 0) {
66                                 keyb[key & 0x7f] = 1;
67                                 for (c1 = 48; c1 > 0; c1--)
68                                         last_keys[c1] = last_keys[c1 - 1];
69                                 last_keys[0] = scancode2ascii[key & 0x7f];
70                         } else
71                                 keyb[key & 0x7f] = 0;
72                 } else {
73                         if ((key & 0x80) == 0) {
74                                 keyb[(key & 0x7f) + 0x80] = 1;
75                                 for (c1 = 48; c1 > 0; c1--)
76                                         last_keys[c1] = last_keys[c1 - 1];
77                                 last_keys[0] = scancode2ascii[(key & 0x7f) + 0x80];
78                         } else
79                                 keyb[(key & 0x7f) + 0x80] = 0;
80                 }
81                 if (extended == 1)
82                         extended = 0;
83         }
84 #ifndef USE_SDL
85         outportb(0x20, 0x20);
86 #endif
87
88 }
89
90 void keyb_handler_end()
91 {
92 }
93
94
95 int hook_keyb_handler(void)
96 {
97 #ifndef USE_SDL
98         if (keyb_handler_info.enabled == 0) {
99                 _go32_dpmi_lock_data((char *) &keyb, sizeof(keyb));
100                 _go32_dpmi_lock_code(keyb_handler, (unsigned long) keyb_handler_end - (unsigned long) keyb_handler);
101                 _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo);
102                 new_keyb_handler_seginfo.pm_offset = (int) keyb_handler;
103                 if (_go32_dpmi_allocate_iret_wrapper(&new_keyb_handler_seginfo) != 0)
104                         return 1;
105                 if (_go32_dpmi_set_protected_mode_interrupt_vector(9, &new_keyb_handler_seginfo) != 0) {
106                         _go32_dpmi_free_iret_wrapper(&new_keyb_handler_seginfo);
107                         return 1;
108                 }
109                 keyb_handler_info.enabled = 1;
110                 memset(last_keys, 0, sizeof(last_keys));
111         }
112 #endif
113         SDL_EnableUNICODE(1);
114         memset((void *) last_keys, 0, sizeof(last_keys));
115         return 0;
116
117 }
118
119
120 void remove_keyb_handler(void)
121 {
122 #ifndef USE_SDL
123         if (keyb_handler_info.enabled == 1) {
124                 _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo);
125                 _go32_dpmi_free_iret_wrapper(&new_keyb_handler_seginfo);
126                 keyb_handler_info.enabled = 0;
127         }
128 #endif
129 }
130
131
132 int key_pressed(int key)
133 {
134         return keyb[(unsigned char) key];
135 }
136
137 int addkey(unsigned int key)
138 {
139         int c1;
140
141         if (!(key & 0x8000)) {
142                 keyb[key & 0x7fff] = 1;
143                 for (c1 = 48; c1 > 0; c1--)
144                         last_keys[c1] = last_keys[c1 - 1];
145                 last_keys[0] = key & 0x7fff;
146         } else
147                 keyb[key & 0x7fff] = 0;
148         return 0;
149 }
150
151 int intr_sysupdate()
152 {
153         SDL_Event e;
154         int i = 0;
155         static Uint32 now, then = 0;
156
157         while (SDL_PollEvent(&e)) {
158                 switch (e.type) {
159                 case SDL_MOUSEBUTTONDOWN:
160                         break;
161                 case SDL_KEYDOWN:
162                 case SDL_KEYUP:
163                         switch (e.key.keysym.sym) {
164                         case SDLK_F12:
165                                 if (e.type == SDL_KEYDOWN) {
166                                         SDL_Quit();
167                                         exit(1);
168                                 }
169                                 break;
170                         case SDLK_F10:
171                                 if (e.type == SDL_KEYDOWN) {
172                                         fs_toggle();
173                                 }
174                                 break;
175                         case SDLK_ESCAPE:
176                                 if (e.type == SDL_KEYUP)
177                                         addkey(1 | 0x8000);
178                                 else
179                                         addkey(1 & 0x7f);
180                                 break;
181                         default:
182                                 e.key.keysym.sym &= 0x7f;
183                                 if (e.type == SDL_KEYUP)
184                                         e.key.keysym.sym |= 0x8000;
185                                 addkey(e.key.keysym.sym);
186
187                                 break;
188                         }
189                         break;
190                 default:
191                         break;
192                 }
193                 i++;
194         }
195         //SDL_Delay(4);
196         now = SDL_GetTicks();
197         if (!then)
198                 SDL_Delay(1);
199         else {
200                 then = (1000 / 60) - (now - then);
201                 if (then > 0 && then < 1000)
202                         SDL_Delay(then);
203         }
204         then = now;
205
206         return i;
207 }