1 /* NetHack 3.6 winhack.c $NHDT-Date: 1432512799 2015/05/25 00:13:19 $ $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 // winhack.cpp : Defines the entry point for the application.
4 //
5
6 #include "winMS.h"
7 #include "hack.h"
8 #include "dlb.h"
9 #include "mhmain.h"
10 #include "mhmap.h"
11
12 extern char orgdir[PATHLEN]; /* also used in pcsys.c, amidos.c */
13
14 extern void nethack_exit(int);
15 static TCHAR *_get_cmd_arg(TCHAR *pCmdLine);
16
17 // Global Variables:
18 NHWinApp _nethack_app;
19
20 // Foward declarations of functions included in this code module:
21 BOOL InitInstance(HINSTANCE, int);
22
23 static void win_hack_init(int, char **);
24 static void __cdecl mswin_moveloop(void *);
25 static BOOL setMapTiles(const char *fname);
26
27 extern boolean pcmain(int, char **);
28
29 #define MAX_CMDLINE_PARAM 255
30
31 int APIENTRY
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nCmdShow)32 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,
33 int nCmdShow)
34 {
35 INITCOMMONCONTROLSEX InitCtrls;
36 HWND nethackWnd;
37 int argc;
38 char *argv[MAX_CMDLINE_PARAM];
39 size_t len;
40 TCHAR *p;
41 TCHAR wbuf[NHSTR_BUFSIZE];
42 char buf[NHSTR_BUFSIZE];
43 boolean resuming;
44
45 early_init();
46
47 /* ensure that we don't access violate on a panic() */
48 windowprocs.win_raw_print = mswin_raw_print;
49 windowprocs.win_raw_print_bold = mswin_raw_print_bold;
50
51 /* init applicatio structure */
52 _nethack_app.hApp = hInstance;
53 _nethack_app.nCmdShow = nCmdShow;
54 _nethack_app.hAccelTable =
55 LoadAccelerators(hInstance, (LPCTSTR) IDC_WINHACK);
56 _nethack_app.hMainWnd = NULL;
57 _nethack_app.hPopupWnd = NULL;
58 _nethack_app.hMenuBar = NULL;
59 _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
60 if (_nethack_app.bmpTiles == NULL)
61 panic("cannot load tiles bitmap");
62 _nethack_app.bmpPetMark =
63 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
64 if (_nethack_app.bmpPetMark == NULL)
65 panic("cannot load pet mark bitmap");
66 _nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
67 _nethack_app.mapTile_X = TILE_X;
68 _nethack_app.mapTile_Y = TILE_Y;
69 _nethack_app.mapTilesPerLine = TILES_PER_LINE;
70 _nethack_app.bNoHScroll = FALSE;
71 _nethack_app.bNoVScroll = FALSE;
72
73 _nethack_app.bCmdPad = !mswin_has_keyboard();
74
75 _nethack_app.bWrapText = TRUE;
76 _nethack_app.bFullScreen = TRUE;
77
78 #if defined(WIN_CE_SMARTPHONE)
79 _nethack_app.bHideScrollBars = TRUE;
80 #else
81 _nethack_app.bHideScrollBars = FALSE;
82 #endif
83
84 _nethack_app.bUseSIP = TRUE;
85
86 // check for running nethack programs
87 nethackWnd = FindWindow(szMainWindowClass, NULL);
88 if (nethackWnd) {
89 // bring on top
90 SetForegroundWindow(nethackWnd);
91 return FALSE;
92 }
93
94 // init controls
95 ZeroMemory(&InitCtrls, sizeof(InitCtrls));
96 InitCtrls.dwSize = sizeof(InitCtrls);
97 InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
98 if (!InitCommonControlsEx(&InitCtrls)) {
99 MessageBox(NULL, TEXT("Cannot init common controls"), TEXT("ERROR"),
100 MB_OK | MB_ICONSTOP);
101 return FALSE;
102 }
103
104 // Perform application initialization:
105 if (!InitInstance(hInstance, nCmdShow)) {
106 return FALSE;
107 }
108
109 /* get command line parameters */
110 p = _get_cmd_arg(
111 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
112 lpCmdLine
113 #else
114 GetCommandLine()
115 #endif
116 );
117 for (argc = 1; p && argc < MAX_CMDLINE_PARAM; argc++) {
118 len = _tcslen(p);
119 if (len > 0) {
120 argv[argc] = _strdup(NH_W2A(p, buf, BUFSZ));
121 } else {
122 argv[argc] = "";
123 }
124 p = _get_cmd_arg(NULL);
125 }
126 GetModuleFileName(NULL, wbuf, BUFSZ);
127 argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
128
129 resuming = pcmain(argc, argv);
130
131 moveloop(resuming);
132
133 return 0;
134 }
135
136 //
137 // FUNCTION: InitInstance(HANDLE, int)
138 //
139 // PURPOSE: Saves instance handle and creates main window
140 //
141 // COMMENTS:
142 //
143 // In this function, we save the instance handle in a global variable
144 // and
145 // create and display the main program window.
146 //
147 BOOL
InitInstance(HINSTANCE hInstance,int nCmdShow)148 InitInstance(HINSTANCE hInstance, int nCmdShow)
149 {
150 return TRUE;
151 }
152
153 PNHWinApp
GetNHApp()154 GetNHApp()
155 {
156 return &_nethack_app;
157 }
158
159 static int
eraseoldlocks()160 eraseoldlocks()
161 {
162 register int i;
163
164 /* cannot use maxledgerno() here, because we need to find a lock name
165 * before starting everything (including the dungeon initialization
166 * that sets astral_level, needed for maxledgerno()) up
167 */
168 for (i = 1; i <= MAXDUNGEON * MAXLEVEL + 1; i++) {
169 /* try to remove all */
170 set_levelfile_name(g.lock, i);
171 (void) unlink(fqname(g.lock, LEVELPREFIX, 0));
172 }
173 set_levelfile_name(g.lock, 0);
174 if (unlink(fqname(g.lock, LEVELPREFIX, 0)))
175 return 0; /* cannot remove it */
176 return (1); /* success! */
177 }
178
179 void
getlock()180 getlock()
181 {
182 const char *fq_lock;
183 char tbuf[BUFSZ];
184 TCHAR wbuf[BUFSZ];
185 HANDLE f;
186 int fd;
187 int choice;
188
189 /* regularize(lock); */ /* already done in pcmain */
190 Sprintf(tbuf, "%s", fqname(g.lock, LEVELPREFIX, 0));
191 set_levelfile_name(g.lock, 0);
192 fq_lock = fqname(g.lock, LEVELPREFIX, 1);
193
194 f = CreateFile(NH_A2W(fq_lock, wbuf, BUFSZ), GENERIC_READ, 0, NULL,
195 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
196 if (f == INVALID_HANDLE_VALUE) {
197 if (GetLastError() == ERROR_FILE_NOT_FOUND)
198 goto gotlock; /* no such file */
199 error("Cannot open %s", fq_lock);
200 }
201
202 CloseHandle(f);
203
204 /* prompt user that the game alredy exist */
205 choice = MessageBox(GetNHApp()->hMainWnd,
206 TEXT("There are files from a game in progress under "
207 "your name. Recover?"),
208 TEXT("Nethack"), MB_YESNO | MB_DEFBUTTON1);
209 switch (choice) {
210 case IDYES:
211 if (recover_savefile()) {
212 goto gotlock;
213 } else {
214 error("Couldn't recover old game.");
215 }
216 break;
217
218 case IDNO:
219 unlock_file(HLOCK);
220 error("%s", "Cannot start a new game.");
221 break;
222 };
223
224 gotlock:
225 fd = creat(fq_lock, FCMASK);
226 if (fd == -1) {
227 error("cannot creat lock file (%s.)", fq_lock);
228 } else {
229 if (write(fd, (char *) &g.hackpid, sizeof(g.hackpid))
230 != sizeof(g.hackpid)) {
231 error("cannot write lock (%s)", fq_lock);
232 }
233 if (close(fd) == -1) {
234 error("cannot close lock (%s)", fq_lock);
235 }
236 }
237 }
238
239 /* misc functions */
240 void error
VA_DECL(const char *,s)241 VA_DECL(const char *, s)
242 {
243 TCHAR wbuf[1024];
244 char buf[1024];
245 DWORD last_error = GetLastError();
246
247 VA_START(s);
248 VA_INIT(s, const char *);
249 /* error() may get called before tty is initialized */
250 if (iflags.window_inited)
251 end_screen();
252
253 vsprintf(buf, s, VA_ARGS);
254 NH_A2W(buf, wbuf, sizeof(wbuf) / sizeof(wbuf[0]));
255 if (last_error > 0) {
256 LPVOID lpMsgBuf;
257 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
258 | FORMAT_MESSAGE_FROM_SYSTEM
259 | FORMAT_MESSAGE_IGNORE_INSERTS,
260 NULL, last_error,
261 0, // Default language
262 (LPTSTR) &lpMsgBuf, 0, NULL)) {
263 _tcsncat(wbuf, TEXT("\nSystem Error: "),
264 sizeof(wbuf) / sizeof(wbuf[0]) - _tcslen(wbuf));
265 _tcsncat(wbuf, lpMsgBuf,
266 sizeof(wbuf) / sizeof(wbuf[0]) - _tcslen(wbuf));
267
268 // Free the buffer.
269 LocalFree(lpMsgBuf);
270 }
271 }
272 MessageBox(NULL, wbuf, TEXT("Error"), MB_OK | MB_ICONERROR);
273 VA_END();
274 exit(EXIT_FAILURE);
275 }
276
277 TCHAR *
_get_cmd_arg(TCHAR * pCmdLine)278 _get_cmd_arg(TCHAR *pCmdLine)
279 {
280 static TCHAR *pArgs = NULL;
281 TCHAR *pRetArg;
282 BOOL bQuoted;
283
284 if (!pCmdLine && !pArgs)
285 return NULL;
286 if (!pArgs)
287 pArgs = pCmdLine;
288
289 /* skip whitespace */
290 for (pRetArg = pArgs; *pRetArg && _istspace(*pRetArg);
291 pRetArg = CharNext(pRetArg))
292 ;
293 if (!*pRetArg) {
294 pArgs = NULL;
295 return NULL;
296 }
297
298 /* check for quote */
299 if (*pRetArg == TEXT('"')) {
300 bQuoted = TRUE;
301 pRetArg = CharNext(pRetArg);
302 pArgs = _tcschr(pRetArg, TEXT('"'));
303 } else {
304 /* skip to whitespace */
305 for (pArgs = pRetArg; *pArgs && !_istspace(*pArgs);
306 pArgs = CharNext(pArgs))
307 ;
308 }
309
310 if (pArgs && *pArgs) {
311 TCHAR *p;
312 p = pArgs;
313 pArgs = CharNext(pArgs);
314 *p = (TCHAR) 0;
315 } else {
316 pArgs = NULL;
317 }
318
319 return pRetArg;
320 }
321
322 /*
323 * Strip out troublesome file system characters.
324 */
325
nt_regularize(s)326 void nt_regularize(s) /* normalize file name */
327 register char *s;
328 {
329 register unsigned char *lp;
330
331 for (lp = s; *lp; lp++)
332 if (*lp == '?' || *lp == '"' || *lp == '\\' || *lp == '/'
333 || *lp == '>' || *lp == '<' || *lp == '*' || *lp == '|'
334 || *lp == ':' || (*lp > 127))
335 *lp = '_';
336 }
337
338 void
win32_abort()339 win32_abort()
340 {
341 if (wizard)
342 DebugBreak();
343 abort();
344 }
345
346 void
append_port_id(buf)347 append_port_id(buf)
348 char *buf;
349 {
350 char *portstr = PORT_CE_PLATFORM " " PORT_CE_CPU;
351 Sprintf(eos(buf), " %s", portstr);
352 }
353