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