1 /* SCCS Id: @(#)os2.c 3.4 1996/02/29 */
2 /* Copyright (c) Timo Hakulinen, 1990, 1991, 1992, 1993, 1996. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 /*
6 * OS/2 system functions.
7 */
8
9 #define NEED_VARARGS
10 #include "hack.h"
11
12 #ifdef OS2
13
14 #include "tcap.h"
15
16 /* OS/2 system definitions */
17
18 #ifdef __EMX__
19 #undef CLR_BLACK
20 #undef CLR_WHITE
21 #undef CLR_BLUE
22 #undef CLR_RED
23 #undef CLR_GREEN
24 #undef CLR_CYAN
25 #undef CLR_YELLOW
26 #undef CLR_BROWN
27 #endif
28
29 #include "def_os2.h"
30
31 #include <ctype.h>
32
33 static char NDECL(DOSgetch);
34 static char NDECL(BIOSgetch);
35
36 int
tgetch()37 tgetch()
38 {
39 char ch;
40
41 /* BIOSgetch can use the numeric key pad on IBM compatibles. */
42 if (iflags.BIOS)
43 ch = BIOSgetch();
44 else
45 ch = DOSgetch();
46 return ((ch == '\r') ? '\n' : ch);
47 }
48
49 /*
50 * Keyboard translation tables.
51 */
52 #define KEYPADLO 0x47
53 #define KEYPADHI 0x53
54
55 #define PADKEYS (KEYPADHI - KEYPADLO + 1)
56 #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
57
58 /*
59 * Keypad keys are translated to the normal values below.
60 * When iflags.BIOS is active, shifted keypad keys are translated to the
61 * shift values below.
62 */
63 static const struct pad {
64 char normal, shift, cntrl;
65 } keypad[PADKEYS] = {
66 {'y', 'Y', C('y')}, /* 7 */
67 {'k', 'K', C('k')}, /* 8 */
68 {'u', 'U', C('u')}, /* 9 */
69 {'m', C('p'), C('p')}, /* - */
70 {'h', 'H', C('h')}, /* 4 */
71 {'g', 'g', 'g'}, /* 5 */
72 {'l', 'L', C('l')}, /* 6 */
73 {'p', 'P', C('p')}, /* + */
74 {'b', 'B', C('b')}, /* 1 */
75 {'j', 'J', C('j')}, /* 2 */
76 {'n', 'N', C('n')}, /* 3 */
77 {'i', 'I', C('i')}, /* Ins */
78 {'.', ':', ':'} /* Del */
79 }, numpad[PADKEYS] = {
80 {'7', M('7'), '7'}, /* 7 */
81 {'8', M('8'), '8'}, /* 8 */
82 {'9', M('9'), '9'}, /* 9 */
83 {'m', C('p'), C('p')}, /* - */
84 {'4', M('4'), '4'}, /* 4 */
85 {'g', 'G', 'g'}, /* 5 */
86 {'6', M('6'), '6'}, /* 6 */
87 {'p', 'P', C('p')}, /* + */
88 {'1', M('1'), '1'}, /* 1 */
89 {'2', M('2'), '2'}, /* 2 */
90 {'3', M('3'), '3'}, /* 3 */
91 {'i', 'I', C('i')}, /* Ins */
92 {'.', ':', ':'} /* Del */
93 };
94
95 /*
96 * Unlike Ctrl-letter, the Alt-letter keystrokes have no specific ASCII
97 * meaning unless assigned one by a keyboard conversion table, so the
98 * keyboard BIOS normally does not return a character code when Alt-letter
99 * is pressed. So, to interpret unassigned Alt-letters, we must use a
100 * scan code table to translate the scan code into a letter, then set the
101 * "meta" bit for it. -3.
102 */
103 #define SCANLO 0x10
104 #define SCANHI 0x32
105 #define SCANKEYS (SCANHI - SCANLO + 1)
106 #define inmap(x) (SCANLO <= (x) && (x) <= SCANHI)
107
108 static const char scanmap[SCANKEYS] = { /* ... */
109 'q','w','e','r','t','y','u','i','o','p','[',']', '\n',
110 0, 'a','s','d','f','g','h','j','k','l',';','\'', '`',
111 0, '\\', 'z','x','c','v','b','N','m' /* ... */
112 };
113
114 /*
115 * BIOSgetch emulates the MSDOS way of getting keys directly with a BIOS call.
116 */
117 #define SHIFT_KEY (0x1 | 0x2)
118 #define CTRL_KEY 0x4
119 #define ALT_KEY 0x8
120
121 static char
BIOSgetch()122 BIOSgetch()
123 {
124 unsigned char scan, shift, ch;
125 const struct pad *kpad;
126
127 KBDKEYINFO CharData;
128 USHORT IOWait = 0;
129 HKBD KbdHandle = 0;
130
131 KbdCharIn(&CharData,IOWait,KbdHandle);
132 ch = CharData.chChar;
133 scan = CharData.chScan;
134 shift = CharData.fsState;
135
136 /* Translate keypad keys */
137 if (iskeypad(scan)) {
138 kpad = iflags.num_pad ? numpad : keypad;
139 if (shift & SHIFT_KEY)
140 ch = kpad[scan - KEYPADLO].shift;
141 else if (shift & CTRL_KEY)
142 ch = kpad[scan - KEYPADLO].cntrl;
143 else
144 ch = kpad[scan - KEYPADLO].normal;
145 }
146 /* Translate unassigned Alt-letters */
147 if ((shift & ALT_KEY) && !ch) {
148 if (inmap(scan))
149 ch = scanmap[scan - SCANLO];
150 return (isprint(ch) ? M(ch) : ch);
151 }
152 return ch;
153 }
154
155 static char
DOSgetch()156 DOSgetch()
157 {
158 KBDKEYINFO CharData;
159 USHORT IOWait = 0;
160 HKBD KbdHandle = 0;
161
162 KbdCharIn(&CharData,IOWait,KbdHandle);
163 if (CharData.chChar == 0) { /* an extended code -- not yet supported */
164 KbdCharIn(&CharData,IOWait,KbdHandle); /* eat the next character */
165 CharData.chChar = 0; /* and return a 0 */
166 }
167 return (CharData.chChar);
168 }
169
170 char
switchar()171 switchar()
172 {
173 return '/';
174 }
175
176 int
kbhit()177 kbhit()
178 {
179 KBDKEYINFO CharData;
180 HKBD KbdHandle = 0;
181
182 KbdPeek(&CharData,KbdHandle);
183 return (CharData.fbStatus & (1 << 6));
184 }
185
186 long
freediskspace(path)187 freediskspace(path)
188 char *path;
189 {
190 FSALLOCATE FSInfoBuf;
191 #ifdef OS2_32BITAPI
192 ULONG
193 #else
194 USHORT
195 #endif
196 DriveNumber, FSInfoLevel = 1, res;
197
198 if (path[0] && path[1] == ':')
199 DriveNumber = (toupper(path[0]) - 'A') + 1;
200 else
201 DriveNumber = 0;
202 res =
203 #ifdef OS2_32BITAPI
204 DosQueryFSInfo(DriveNumber,FSInfoLevel,(PVOID)&FSInfoBuf,(ULONG)sizeof(FSInfoBuf));
205 #else
206 DosQFSInfo(DriveNumber,FSInfoLevel,(PBYTE)&FSInfoBuf,(USHORT)sizeof(FSInfoBuf));
207 #endif
208 if (res)
209 return -1L; /* error */
210 else
211 return ((long) FSInfoBuf.cSectorUnit * FSInfoBuf.cUnitAvail *
212 FSInfoBuf.cbSector);
213 }
214
215 /*
216 * Functions to get filenames using wildcards
217 */
218
219 #ifdef OS2_32BITAPI
220 static FILEFINDBUF3 ResultBuf;
221 #else
222 static FILEFINDBUF ResultBuf;
223 #endif
224 static HDIR DirHandle;
225
226 int
findfirst(path)227 findfirst(path)
228 char *path;
229 {
230 #ifdef OS2_32BITAPI
231 ULONG
232 #else
233 USHORT
234 #endif
235 res, SearchCount = 1;
236
237 DirHandle = 1;
238 res =
239 #ifdef OS2_32BITAPI
240 DosFindFirst((PSZ)path,&DirHandle,0L,(PVOID)&ResultBuf,(ULONG)sizeof(ResultBuf),&SearchCount,1L);
241 #else
242 DosFindFirst((PSZ)path,&DirHandle,0,&ResultBuf,(USHORT)sizeof(ResultBuf),&SearchCount,0L);
243 #endif
244 return(!res);
245 }
246
247 int
findnext()248 findnext()
249 {
250 #ifdef OS2_32BITAPI
251 ULONG
252 #else
253 USHORT
254 #endif
255 res, SearchCount = 1;
256
257 res =
258 #ifdef OS2_32BITAPI
259 DosFindNext(DirHandle,(PVOID)&ResultBuf,(ULONG)sizeof(ResultBuf),&SearchCount);
260 #else
261 DosFindNext(DirHandle,&ResultBuf,(USHORT)sizeof(ResultBuf),&SearchCount);
262 #endif
263 return(!res);
264 }
265
266 char *
foundfile_buffer()267 foundfile_buffer()
268 {
269 return(ResultBuf.achName);
270 }
271
272 long
filesize(file)273 filesize(file)
274 char *file;
275 {
276 if (findfirst(file)) {
277 return (* (long *) (ResultBuf.cbFileAlloc));
278 } else
279 return -1L;
280 }
281
282 /*
283 * Chdrive() changes the default drive.
284 */
285 void
chdrive(str)286 chdrive(str)
287 char *str;
288 {
289 char *ptr;
290 char drive;
291
292 if ((ptr = index(str, ':')) != (char *)0) {
293 drive = toupper(*(ptr - 1));
294 #ifdef OS2_32BITAPI
295 DosSetDefaultDisk((ULONG)(drive - 'A' + 1));
296 #else
297 DosSelectDisk((USHORT)(drive - 'A' + 1));
298 #endif
299 }
300 }
301
302 void
disable_ctrlP()303 disable_ctrlP()
304 {
305 KBDINFO KbdInfo;
306 HKBD KbdHandle = 0;
307
308 if (!iflags.rawio) return;
309 KbdInfo.cb = sizeof(KbdInfo);
310 KbdGetStatus(&KbdInfo,KbdHandle);
311 KbdInfo.fsMask &= 0xFFF7; /* ASCII off */
312 KbdInfo.fsMask |= 0x0004; /* BINARY on */
313 KbdSetStatus(&KbdInfo,KbdHandle);
314 }
315
316 void
enable_ctrlP()317 enable_ctrlP()
318 {
319 KBDINFO KbdInfo;
320 HKBD KbdHandle = 0;
321
322 if (!iflags.rawio) return;
323 KbdInfo.cb = sizeof(KbdInfo);
324 KbdGetStatus(&KbdInfo,KbdHandle);
325 KbdInfo.fsMask &= 0xFFFB; /* BINARY off */
326 KbdInfo.fsMask |= 0x0008; /* ASCII on */
327 KbdSetStatus(&KbdInfo,KbdHandle);
328 }
329
330 void
get_scr_size()331 get_scr_size()
332 {
333 VIOMODEINFO ModeInfo;
334 HVIO VideoHandle = 0;
335
336 ModeInfo.cb = sizeof(ModeInfo);
337
338 (void) VioGetMode(&ModeInfo,VideoHandle);
339
340 CO = ModeInfo.col;
341 LI = ModeInfo.row;
342 }
343
344 void
gotoxy(x,y)345 gotoxy(x,y)
346 int x,y;
347 {
348 HVIO VideoHandle = 0;
349
350 x--; y--; /* (0,0) is upper right corner */
351
352 (void) VioSetCurPos(x, y, VideoHandle);
353 }
354
355
get_username(lan_username_size)356 char* get_username(lan_username_size)
357 int *lan_username_size;
358 {
359 return (char*)0;
360 }
361 #ifdef X11_GRAPHICS
362 int errno;
363 #endif
364 #endif /* OS2 */
365