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