1 /*	SCCS Id: @(#)winmain.c	3.2	95/09/06	*/
2 /* Copyright (c) NetHack PC Development Team 1995                 */
3 /* NetHack may be freely redistributed.  See license for details. */
4 /* Builds on original MS Windows 3.1.0 Port code by Bill Dyer       */
5 
6 #include "hack.h"
7 
8 #ifdef WIN32_GRAPHICS
9 
10 # ifndef NO_SIGNAL
11 #include <signal.h>
12 # endif
13 #include <ctype.h>
14 #include <sys\stat.h>
15 #include "win32api.h"
16 #include "nhwin32.h"
17 
18 extern struct window_procs win32_procs;
19 static int getargs(char *cmdline);
20 extern int main(int argc, char *argv[]);	/* in sys/share/pcmain.c */
21 
22 int winmode;
23 int HaveConsole;
24 int argc;
25 int NHnCmdShow;
26 char *xargv[20];
27 
28 WNDCLASS wcNetHack;
29 WNDCLASS wcNHText;
30 WNDCLASS wcNHPopup;
31 WNDCLASS wcNHListbox;
32 char GameName[]="NetHack";
33 char NHTextClassName[] = "NHTextWin";
34 char NHPopupClassName[] = "NHPopupWin";
35 char NHListboxClassName[] = "NHListboxWin";
36 
37 HINSTANCE NHhPreInst;
38 HWND BasehWnd;
39 char winstyle[20];
40 char NHMenu[]="AboutMenu";
41 
42 unsigned char *pchBuf;
43 unsigned char *pchGet;
44 unsigned char *pchPut;
45 int pchCount;
46 int BaseUnits;
47 int BaseHeight;
48 int BaseWidth;
49 int MessageHeight;
50 int MessageWidth;
51 int MessageX;
52 int MessageY;
53 int MessageCount;
54 char *MessagePtr[MAX_MESSAGE_COUNT];
55 int MapHeight;
56 int MapWidth;
57 int MapX;
58 int MapY;
59 int StatusHeight;
60 int StatusWidth;
61 int StatusX;
62 int StatusY;
63 int tiles_on;
64 int DefCharWidth;
65 int DefCharHeight;
66 int DefBackGroundColor;
67 int DefNormalTextColor;
68 struct win32_menuitem *MenuPtr[MAX_MENU_WINDOWS][MAX_INVENTORY];
69 int MenuCount[MAX_MENU_WINDOWS];
70 int MenuWindowCount = 0;
71 HFONT hDefFnt;
72 TEXTMETRIC tm;
73 RECT rcClient;
74 int inputstatus;
75 char input_text[BUFSZ];
76 int input_text_size;
77 
78 COLORREF colormap[] = {
79 	RGB(  0,  0,  0),	/* BLACK      */
80 	RGB(255,  0,  0),	/* RED        */
81 	RGB(  0,160,  0),	/* GREEN      */
82 	RGB(200,160, 20),	/* BROWN      */
83 	RGB(  0,  0,160),	/* BLUE       */
84 	RGB(160,  0,160),	/* MAGENTA    */
85 	RGB(  0,160,160),	/* CYAN       */
86 	RGB(200,200,200),	/* GRAY       */
87 	RGB(  0,  0,  0),	/* NO_COLOR   */
88 	RGB(100,255,  0),	/* ORANGE     */
89 	RGB(  0,255,  0),	/* BR GREEN   */
90 	RGB(255,255,  0),	/* YELLOW     */
91 	RGB(  0,  0,255),	/* BR BLUE    */
92 	RGB(255,  0,255),	/* BR MAGENTA */
93 	RGB(  0,255,255),	/* BR CYAN    */
94 	RGB(255,255,255)	/* WHITE      */
95 };
96 
WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpszCmdLine,int nCmdShow)97 int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPreInst, LPSTR lpszCmdLine,
98 		   int nCmdShow)
99 {
100 	int tmp;
101 
102 	HaveConsole = 0;
103 	wcNetHack.hInstance = hInst;
104 	NHhPreInst = hPreInst;
105 	NHnCmdShow = nCmdShow;
106 	argc = getargs(lpszCmdLine);
107 	/* temporary */
108 	if (getenv("WINMODE") != (char *)0) {
109 		if (strncmpi("WIN32",getenv("WINMODE"),5) == 0)
110 			winmode = WINMODE_WIN32;
111 	}
112 	switch(winmode) {
113 # ifndef WIN32S
114 		case WINMODE_TTY:
115 			strcpy(winstyle,"tty");
116 			tmp = AllocConsole();
117 			if (tmp) HaveConsole = 1;
118 			break;
119 # endif
120 
121 		case WINMODE_WIN32:
122 			strcpy(winstyle,"win32");
123 			break;
124 		default:
125 			strcpy(winstyle,DEFAULT_WINDOW_SYS);
126 			break;
127 	}
128 	choose_windows(winstyle);
129 	return main(argc, xargv);
130 }
131 
132 int
getargs(char * cmdline)133 getargs(char *cmdline)
134 {
135 	int maxchars;
136 	int count;
137 	int argcount = 1;
138 	int between = 0;
139 	char *tmpbuf;
140 
141 
142 	xargv[0] = "nethack.exe";
143 	if (strlen(cmdline) == 0)
144 		return argcount;
145 
146 	tmpbuf = (char *)alloc(strlen(cmdline)+1);
147 	strcpy(tmpbuf,cmdline);
148 
149 	xargv[argcount] = (char *)&tmpbuf[0];
150 	++argcount;
151 	maxchars = strlen(tmpbuf);
152 	for (count = 0; count < maxchars; ++count)
153 	{
154 		if (!between) {
155 			if (isspace(tmpbuf[count])) {
156 				between = 1;
157  				tmpbuf[count] = '\0';
158 			}
159 		} else {
160 			if (!isspace(tmpbuf[count])) {
161 				between = 0;
162 				xargv[argcount] = (char *)&tmpbuf[count];
163 				++argcount;
164 			}
165 		}
166 	}
167 	return argcount;
168 }
169 
InitBaseWindow(void)170 BOOL InitBaseWindow(void)
171 {
172 	if (!NHhPreInst) {
173 		wcNetHack.lpszClassName="NHBaseWin";
174 		wcNetHack.lpfnWndProc  =BaseWndProc;
175 		wcNetHack.hCursor      =LoadCursor((HINSTANCE)0,IDC_ARROW);
176 		wcNetHack.hIcon        =LoadIcon(wcNetHack.hInstance,
177 					"NETHACK_");
178 		wcNetHack.lpszMenuName ="NHMenu";
179 		wcNetHack.hbrBackground=GetStockObject(BLACK_BRUSH);
180 		wcNetHack.style        =CS_HREDRAW|CS_VREDRAW;
181 		wcNetHack.cbClsExtra   =0;
182 		wcNetHack.cbWndExtra   =0;
183 		if (!RegisterClass (&wcNetHack)) {
184 			return FALSE;
185 		}
186 	}
187 	BasehWnd = CreateWindow("NHBaseWin",
188 				"NetHack 3.1",
189 				WS_OVERLAPPEDWINDOW,
190 				CW_USEDEFAULT,
191 				CW_USEDEFAULT,
192 				CW_USEDEFAULT,
193 				CW_USEDEFAULT,
194 				(HWND)0,
195 				(HMENU)0,
196 				wcNetHack.hInstance,
197 				(LPSTR)0);
198 	return 1;
199 }
200 
InitTextWindow(void)201 BOOL InitTextWindow(void)
202 {
203 	ATOM status;
204 
205 	wcNHText.hInstance    =wcNetHack.hInstance;
206 	wcNHText.lpszClassName=NHTextClassName;
207 	wcNHText.lpfnWndProc  =TextWndProc;
208 	wcNHText.hCursor      =LoadCursor((HINSTANCE)0,IDC_ARROW);
209 	wcNHText.hIcon        =LoadIcon(0,IDI_APPLICATION);
210 	wcNHText.lpszMenuName =(char *)0;
211 	wcNHText.hbrBackground=GetStockObject(BLACK_BRUSH);
212 	wcNHText.style        =CS_HREDRAW|CS_VREDRAW;
213 	wcNHText.cbClsExtra   =0;
214 	wcNHText.cbWndExtra   =0;
215 
216 	status = RegisterClass(&wcNHText);
217 	if (status == (ATOM)0) return 0;
218 	else return 1;
219 }
220 
InitPopupWindow(void)221 BOOL InitPopupWindow(void)
222 {
223 	ATOM status;
224 
225 	wcNHPopup.hInstance    =wcNetHack.hInstance;
226 	wcNHPopup.lpszClassName=NHPopupClassName;
227 	wcNHPopup.lpfnWndProc  =PopupWndProc;
228 	wcNHPopup.hCursor      =LoadCursor((HINSTANCE)0,IDC_ARROW);
229 	wcNHPopup.hIcon        =LoadIcon(0,IDI_APPLICATION);
230 	wcNHPopup.lpszMenuName =(char *)0;
231 	wcNHPopup.hbrBackground=GetStockObject(BLACK_BRUSH);
232 	wcNHPopup.style        =CS_HREDRAW|CS_VREDRAW;
233 	wcNHPopup.cbClsExtra   =0;
234 	wcNHPopup.cbWndExtra   =0;
235 
236 	status = RegisterClass(&wcNHPopup);
237 	if (status == (ATOM)0) return 0;
238 	else return 1;
239 }
240 
InitListboxWindow(void)241 BOOL InitListboxWindow(void)
242 {
243 	ATOM status;
244 
245 	wcNHListbox.hInstance    =wcNetHack.hInstance;
246 	wcNHListbox.lpszClassName=NHListboxClassName;
247 	wcNHListbox.lpfnWndProc  =ListboxWndProc;
248 	wcNHListbox.hCursor      =LoadCursor((HINSTANCE)0,IDC_ARROW);
249 	wcNHListbox.hIcon        =LoadIcon(0,IDI_APPLICATION);
250 	wcNHListbox.lpszMenuName =(char *)0;
251 	wcNHListbox.hbrBackground=GetStockObject(WHITE_BRUSH);
252 	wcNHListbox.style        =CS_HREDRAW|CS_VREDRAW;
253 	wcNHListbox.cbClsExtra   =0;
254 	wcNHListbox.cbWndExtra   =0;
255 
256 	status = RegisterClass(&wcNHListbox);
257 	if (status == (ATOM)0) return 0;
258 	else return 1;
259 }
260 
261 void
win_win32_init()262 win_win32_init()
263 {
264 	nt_kbhit = win32_kbhit;
265 }
266 
267 int
win32_kbhit()268 win32_kbhit()
269 {
270 	return pchCount;
271 }
272 
273 /*
274  *  Virtual Key translation tables.
275  *  (Adopted from the MSDOS port)
276  */
277 
278 #define VKEYPADLO	0x60
279 #define VKEYPADHI	0x6E
280 
281 #define VPADKEYS 	(VKEYPADHI - VKEYPADLO + 1)
282 #define isvkeypad(x)	(VKEYPADLO <= (x) && (x) <= VKEYPADHI)
283 
284 
285 /*
286  * Keypad keys are translated to the normal values below from
287  * Windows virtual keys. Shifted keypad keys are translated to the
288  * shift values below.
289  */
290 static const struct vkpad {
291 	uchar normal, shift, cntrl;
292 } vkeypad[VPADKEYS] = {
293 			{'i', 'I', C('i')},		/* Ins */
294 			{'b', 'B', C('b')},		/* 1 */
295 			{'j', 'J', C('j')},		/* 2 */
296 			{'n', 'N', C('n')},		/* 3 */
297 			{'h', 'H', C('h')},		/* 4 */
298 			{'g', 'g', 'g'},		/* 5 */
299 			{'l', 'L', C('l')},		/* 6 */
300 			{'y', 'Y', C('y')},		/* 7 */
301 			{'k', 'K', C('k')},		/* 8 */
302 			{'u', 'U', C('u')},		/* 9 */
303 			{ 0 ,   0,      0},		/* * */
304 			{'p', 'P', C('p')},		/* + */
305 			{ 0 ,   0,      0},		/* sep */
306 			{'m', C('p'), C('p')},		/* - */
307 			{'.', ':', ':'}			/* Del */
308 }, vnumpad[VPADKEYS] = {
309 			{'i', 'I', C('i')},		/* Ins */
310 			{'1', M('1'), '1'},		/* 1 */
311 			{'2', M('2'), '2'},		/* 2 */
312 			{'3', M('3'), '3'},		/* 3 */
313 			{'4', M('4'), '4'},		/* 4 */
314 			{'g', 'G', 'g'},		/* 5 */
315 			{'6', M('6'), '6'},		/* 6 */
316 			{'7', M('7'), '7'},		/* 7 */
317 			{'8', M('8'), '8'},		/* 8 */
318 			{'9', M('9'), '9'},		/* 9 */
319 			{ 0 ,   0,      0},		/* * */
320 			{'p', 'P', C('p')},		/* + */
321 			{ 0 ,   0,      0},		/* sep */
322 			{'m', C('p'), C('p')},		/* - */
323 			{'.', ':', ':'}			/* Del */
324 };
325 
326 /*
327  * Unlike Ctrl-letter, the Alt-letter keystrokes have no specific ASCII
328  * meaning unless assigned one by a virtual key conversion table.
329  * To interpret Alt-letters, we use a virtual key code table to
330  * translate the virtual key code into a letter, then set the "meta"
331  * bit for it.
332  */
333 static const char vkmap[] = { 	/* ... */
334 	'a','b','c','d','e','f','g','h','i','j','k','l','m',
335 	'n','o','p','q','r','s','t','u','v','w','x','y','z'
336 };
337 #define VKLO		0x41
338 #define invkmap(x)      (VKLO <= (x) && (x) < VKLO + SIZE(vkmap))
339 
340 
341 #endif /* WIN32_GRAPHICS */
342